免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2742 | 回复: 12
打印 上一主题 下一主题

请教mmap的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-07-21 20:56 |只看该作者 |倒序浏览
一个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. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2010-07-21 21:03 |只看该作者
就是把磁盘里面的文件映射到内存,原来需要读磁盘,现在只要访问内存即可,所以你会感到差那么多倍,就是因为访存和访问磁盘的的读取时间数量级的不同{:3_180:}这个问题不应该在内核区问。。。也就我这种刷帖子的人回答你了

论坛徽章:
0
3 [报告]
发表于 2010-07-21 21:36 |只看该作者
本帖最后由 KennyHIT 于 2010-07-21 21:55 编辑

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

论坛徽章:
1
天蝎座
日期:2013-10-23 21:11:03
4 [报告]
发表于 2010-07-21 21:39 |只看该作者
第一次应该会读磁盘后再读内存
第二次的应该是查找内存后再读内存
LZ试着操作文件的不同部分,然后再统计一下时间
看看有没有什么变化

论坛徽章:
0
5 [报告]
发表于 2010-07-21 21:43 |只看该作者
试着运行了一下LZ的程序,没有看到传说中的神奇现象,很失望……

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

论坛徽章:
0
6 [报告]
发表于 2010-07-21 21:46 |只看该作者
回复 4# 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秒吧。
应该不是读硬盘的事,希望大家帮忙解答一下。

论坛徽章:
0
7 [报告]
发表于 2010-07-21 21:49 |只看该作者
试着运行了一下LZ的程序,没有看到传说中的神奇现象,很失望……

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



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

论坛徽章:
0
8 [报告]
发表于 2010-07-21 21:53 |只看该作者
我把代码中的
  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

只是原来的两倍时间。

论坛徽章:
0
9 [报告]
发表于 2010-07-21 22:16 |只看该作者
回复 3# KennyHIT


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

论坛徽章:
0
10 [报告]
发表于 2010-07-21 22:20 |只看该作者
回复  KennyHIT


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



    我去掉注释后,反而慢300倍的时间,文件大小是9兆,内核版本是2.6.9-67.ELsmp ,64位的cpu
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP