+ -
当前位置:首页 → 问答吧 → 请教mmap的问题

请教mmap的问题

时间:2010-07-21

来源:互联网

一个mmap的问题,不知道发在本版合不合适,请大家指教。
如下代码,去掉那行注释,执行速度会慢300倍。前后区别就是把一个文件mmap了两次,性能差距这么大,mmap到底做了什么工作呢?
  1. int main(int argc, char **argv){
  2.         if(argc != 2){
  3.                 printf("usage: %s file_name\n",argv[0]);
  4.                 return EXIT_FAILURE;
  5.         }

  6.         char *file_name = argv[1];
  7.         struct stat st;
  8.         size_t file_len = 0;
  9.         if(stat(file_name, &st) < 0){
  10.                 printf("The file [%s] not exist or not readable!\n",file_name);
  11.                 return EXIT_FAILURE;
  12.         }
  13.         file_len = st.st_size;
  14.         int fd_map = open(file_name,O_RDWR);
  15.         char *map_ro = (char*)mmap(0, file_len, PROT_READ, MAP_PRIVATE, fd_map, 0);
  16.         char *map_rw = (char*)mmap(0, file_len, PROT_READ, MAP_PRIVATE, fd_map, 0);
  17.         char c = '0';
  18.         size_t i = 0;
  19.         for(i=0;i<file_len; i++){
  20.                 c=map_ro[i];
  21.         //      c=map_rw[i];
  22.         }
  23.         munmap(map_ro,file_len);
  24.         munmap(map_rw,file_len);
  25.         close(fd_map);
  26.         return EXIT_SUCCESS;
  27. }
复制代码

作者: KennyHIT   发布时间: 2010-07-21

就是把磁盘里面的文件映射到内存,原来需要读磁盘,现在只要访问内存即可,所以你会感到差那么多倍,就是因为访存和访问磁盘的的读取时间数量级的不同这个问题不应该在内核区问。。。也就我这种刷帖子的人回答你了

作者: kgn28   发布时间: 2010-07-21

本帖最后由 KennyHIT 于 2010-07-21 21:55 编辑

不是吧,两者应该都是读内存吧。同时谢谢楼上的回答。我也觉得发在本版不是很合适,不过有两个原因,1是觉得可能涉及到内核的一些原理,2是本版高手多。

作者: KennyHIT   发布时间: 2010-07-21

第一次应该会读磁盘后再读内存
第二次的应该是查找内存后再读内存
LZ试着操作文件的不同部分,然后再统计一下时间
看看有没有什么变化

作者: openspace   发布时间: 2010-07-21

试着运行了一下LZ的程序,没有看到传说中的神奇现象,很失望……

另外,不管是直接read,还是mmap后读内存,本质上都是一样的,都是从磁盘或者文件cache去读的。

作者: kouu   发布时间: 2010-07-21

回复 openspace


    去掉注释前:
$time ./detect_vm_layout kk  
real    0m0.030s
user    0m0.026s
sys     0m0.004s

去掉注释后:
$time ./detect_vm_layout  kk
real    0m7.816s
user    0m7.806s
sys     0m0.009s

每次执行都是两遍以上后的结果

文件kk的大小9兆多一点。即使在一般的pc机上cp一个十兆的文件也用不了7秒吧。
应该不是读硬盘的事,希望大家帮忙解答一下。

作者: KennyHIT   发布时间: 2010-07-21



QUOTE:
试着运行了一下LZ的程序,没有看到传说中的神奇现象,很失望……

另外,不管是直接read,还是mmap后读内 ...
kouu 发表于 2010-07-21 21:43




    不是吧,我的系统是Red Hat Enterprise Linux AS release 4 (Nahant Update 6),你用的什么系统?

作者: KennyHIT   发布时间: 2010-07-21

我把代码中的
  1. for(i=0;i<file_len; i++){
  2.                 c=map_ro[i];
  3.                  c=map_rw[i];
  4.         }
  5.         
复制代码
改为
  1. for(i=0;i<file_len; i++){
  2.                 c=map_ro[i];
  3.         }
  4.         for(i=0;i<file_len; i++){
  5.                 c=map_rw[i];
  6.         }
复制代码
执行结果:
$time ./detect_vm_layout kk
real    0m0.058s
user    0m0.047s
sys     0m0.011s

只是原来的两倍时间。

作者: KennyHIT   发布时间: 2010-07-21

回复 KennyHIT


    是我错了,没仔细看你的程序。
我试了一下,30和24内核,读2MB文件,运行时间上都没有区别。
不过,应该考虑的问题是,你测试的时候,如果两次测试间隔时间较近,系统又是比较空闲,那么,第一次map之后,由于已经把文件读上来,那么第二次(去掉注释再编译)测试的时候,对应文件的inode->address_space的基树里面已经有磁盘的页缓冲了,不需要再读磁盘了,所以测试运行时间会不一样。不知道你测试的时候map多大的文件?

作者: kgn28   发布时间: 2010-07-21



QUOTE:
回复  KennyHIT


    是我错了,没仔细看你的程序。
我试了一下,30和24内核,读2MB文件,运行时间上 ...
kgn28 发表于 2010-07-21 22:16




    我去掉注释后,反而慢300倍的时间,文件大小是9兆,内核版本是2.6.9-67.ELsmp ,64位的cpu

作者: KennyHIT   发布时间: 2010-07-21

热门下载

更多