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

时间:2012-03-22 06:04:08

标签: c linux mmap dma

  

可能重复:
  mmap() vs. reading blocks

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

  • mmap()不按顺序阅读。
  • mmap()必须从磁盘本身获取与read()
  • 相同的内容
  • 映射区域不是连续的 - 所以没有DMA(?)。

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

3 个答案:

答案 0 :(得分:49)

  

我听说(在互联网上读到它)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还有其他原因:

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

这也是为什么mmap可能会变慢的原因 - 请阅读Linus Torvald的post here来说mmap

  

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

另一个his posts

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

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

  •   

FWIW,这是我工作的最后一次出现,内存映射输入比fread等人快80%,用于将二进制数据库记录读入专有数据库,在64位Linux上使用~170GB文件。 / p>

答案 1 :(得分:9)

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

答案 2 :(得分:5)

绝对值“更快”不存在。您必须指定约束和环境。

  

mmap()不按顺序读取。

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

  

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

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

  

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

见上文

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

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