Possible Duplicate:
mmap() vs. reading blocks

我听说(在网上某处读到)mmap()比顺序IO快.对吗?如果是,那么为什么更快?

  • mmap()不是按顺序读的.
  • mmap()必须像read()一样从磁盘本身获取数据
  • 映射区域不是连续的,因此没有DMA(?).

所以从一个文件来看,mmap()应该比read()慢?我上面的哪些假设是错误的?

推荐答案

我听说(在网上某处读到)mmap()比顺序IO快.对吗?如果是,那么为什么更快?

它可以是——有优点也有缺点,如下所列.When you really have reason to care, always benchmark both

除了实际的IO效率之外,应用程序代码在需要进行I/O和数据处理/生成时的跟踪方式也会产生影响,这有时会极大地影响性能.

1) mmap()未按顺序读取.

所以mmap()实际上应该比从文件中读取()慢?我上面的哪些假设是错误的?

1) 这是错误的...mmap()指定与文件内容对应的虚拟地址空间区域...每当访问该地址空间中的页面时,就会发现物理RAM支持虚拟地址,相应的磁盘内容就会出现故障,进入该RAM.因此,从磁盘读取的顺序与访问顺序相匹配.这是一种"懒惰"的I/O机制.例如,如果您需要索引到一个要从磁盘读取的巨大哈希表中,那么读取文件并开始进行访问意味着磁盘I/O不是按顺序进行的,因此可能会导致在将整个文件读入内存之前经过更长的时间,但是,尽管这种情况正在发生,但查找正在成功,并且可以进行相关工作,如果文件的某些部分从来都不是真正需要的,它们就不会被读取(考虑到磁盘和内存页的粒度,即使在使用内存映射时,许多操作系统也允许您指定一些关于计划访问模式的性能增强/内存效率提示,以便他们可以主动提前读取或更积极地释放内存,知道您不太可能返回内存).

2) 绝对正确

3) "映射区域不连续"是模糊的.内存映射区域在虚拟地址空间中是"连续的"(连续的).我们在上面讨论了磁盘I/O的顺序.或者,你在想别的什么吗?无论如何,当页面出现故障时,它们可能确实是使用DMA传输的.

此外,内存映射可能优于常规I/O还有其他原因:

  • there's less copying:
    • 通常是OS&;库级 routine 在数据到达应用程序指定的缓冲区之前通过一个或多个缓冲区传递数据,然后应用程序动态分配存储,然后从I/O缓冲区复制到该存储区,以便在文件读取完成后数据可用
    • 内存映射允许(但不强制)就地使用(您可以只记录指针和可能的长度)
  • 内存映射可以简化应用程序的解析工作,让应用程序将整个文件内容视为可访问的,而不必担心何时读取另一个缓冲区已满
  • 应用程序更多地依赖于操作系统的智慧,在任何一个时间点重新计算物理RAM中的页面数量,从而有效地与应用程序共享直接访问磁盘缓存
  • 以及下面的 comments ,"使用内存映射通常使用更少的系统调用"
  • 如果多个进程正在访问同一个文件,它们应该能够共享物理备份页

这也是mmap速度较慢的原因——请阅读莱纳斯·托瓦尔德(Linus Torvald)的post here,其中提到mmap:

...页桌游戏伴随着失误(甚至只是TLB失误)

从另一个his posts人中:

  • 相当明显的安装和拆卸成本.我是说noticeable.这就像是按照页面表来清晰地取消映射一样.这是维护所有映射列表的簿记.这是解除映射后需要的TLB刷新.

  • 页面错误是昂贵的.这就是映射的填充方式,而且非常慢.

FWIW,上次我在工作中出现这种情况时,内存映射输入比fread等在64位Linux上读取二进制数据库记录到专有数据库的速度快80%,文件大小约为170GB.

Linux相关问答推荐

Azure Linux B1s VM-Jenkins Sever已安装,但主页未打开

Rust unix 进程

访问证书里面的图片

使用 sed 从文本文件中删除特定字符串

从 Ansible 中的 shell 命令输出中提取特定数据

如何忽略 diff 命令中的一些差异?

在没有root访问权限的情况下安装zsh?

如何在 Ubuntu 上安装 chkconfig?

linux远程执行命令

使用 C/C++ (GCC/G++) 在 Linux 中的套接字编程中发送和接收文件

Linux 上 pid_t、uid_t、gid_t 的大小

crontab 命令单独一行

用于数据库备份的 Linux shell 脚本

如何知道linux调度器时间片?

使用 C++ 和 Linux 的高分辨率计时器?

在类 Unix 系统中上次运行的 cron 作业(job)的详细信息?

id_rsa.pub 文件 SSH 错误:格式无效

具有所有内核的 Gzip

find -name "*.xyz" -o -name "*.abc" -exec 对所有找到的文件执行,而不仅仅是指定的最后一个后缀

如何拖尾除第一行以外的所有行