为什么mmap()比顺序IO更快?

Lun*_*oms 39 c linux mmap dma

可能重复:
mmap()与读取块

我听说(在互联网上读取它)mmap()比顺序IO更快.它是否正确?如果是,那为什么它更快?

  • mmap() 不按顺序阅读.
  • mmap()具有从盘面本身一样去取read()
  • 映射区域不是顺序的 - 所以没有DMA(?).

那么mmap()实际上应该比read()文件慢吗?我上面的哪些假设是错误的?

Ton*_*roy 55

我听说(在互联网上读到它)mmap()比顺序IO快.它是否正确?如果是,那为什么它更快?

它可以是 - 有利有弊,如下所列. 如果你真的有理由关心,请始终对两者进行基准测试.

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

1)mmap()不是按顺序读取的.2)mmap()必须从磁盘本身获取与read()相同3)映射区域不是顺序的 - 所以没有DMA(?).

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

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

2)绝对正确

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

此外,存储器映射可能优于通常的I/O还有其他原因:

  • 复制较少:
    • 通常操作系统和库级别例程在到达应用程序指定的缓冲区之前通过一个或多个缓冲区传递数据,然后应用程序动态分配存储,然后从I/O缓冲区复制到该存储,以便在文件读取完成后数据可用
    • 内存映射允许(但不强制)就地使用(您可以只记录指针和可能的长度)
      • 继续访问数据就地风险增加后续交换:文件/内存映射可能比可以解析它的数据结构更冗长,因此其中数据的访问模式可能会在更多内存页面中出现更多错误延迟
  • 内存映射可以通过让应用程序将整个文件内容视为可访问来简化应用程序的解析作业,而不是担心何时读取另一个缓冲区已满
  • 应用程序更多地依赖于操作系统在任何单个时间点在物理RAM中的智能数量,有效地与应用程序共享直接访问磁盘缓存
  • 如下所述,"使用内存映射,您通常使用较少的系统调用"
  • 如果多个进程正在访问同一文件,则它们应该能够共享物理后备页面

这也是为什么mmap可能会变慢的原因- 请阅读Linus Torvald的帖子,其中说mmap:

...页面表游戏连同故障(甚至只是TLB未命中)开销很容易超过以漂亮的流媒体方式复制页面的成本......

并从他的一篇文章:

  • 非常明显的设置和拆卸成本.我的意思是显而易见的.这就像跟随页面表一样干净地取消映射.它是用于维护所有映射列表的簿记.这是取消映射后需要的TLB刷新.

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

FWIW,这是我工作的最后一次出现,内存映射输入比fread用于将二进制数据库记录读取到专有数据库(在具有~170GB文件的64位Linux上)快80%.

  • 很好的答案.同样使用内存管理,通常使用较少的系统调用.这可能导致随机访问读取的显着加速(即每次"读取"之前的"lseek"). (6认同)

J-1*_*DiZ 9

  1. mmap() 可以在进程之间共享.
  2. 只要有可能就会使用DMA.DMA不需要连续的内存 - 许多高端卡支持分散 - 聚集DMA.
  3. 如果可能,可以与内核块高速缓存共享存储区域.所以有出租人复制.
  4. 内存mmap由内核分配,始终对齐.


Jen*_*edt 5

绝对意义上的"更快"并不存在.您必须指定约束和环境.

mmap()不是按顺序读取的.

什么让你有那个想法?如果您确实按顺序访问映射的内存,系统通常会按该顺序获取页面.

mmap()必须从磁盘本身获取,与read()相同

确定,但操作系统确定时间和缓冲区大小

映射区域不是顺序的 - 所以没有DMA(?).

往上看

mmap帮助的是没有涉及额外的用户空间缓冲区,"读取"发生在操作系统内核认为合适的地方以及可以优化的块中.这可能是速度的一个优势,但首先这只是一个更容易使用的界面.

如果您想了解特定设置(硬件,操作系统,使用模式)的速度,您必须进行测量.