我听说(在互联网上读到它)mmap()
比顺序IO快。它是否正确?如果是,那为什么它更快?
mmap()
不按顺序阅读。mmap()
必须从磁盘本身获取与read()
所以mmap()
实际上应该比文件中的read()
慢?我上面的哪些假设是错误的?
答案 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还有其他原因:
这也是为什么mmap
可能会变慢的原因 - 请阅读Linus Torvald的post here来说mmap
:
...页面游戏以及故障(甚至只是TLB未命中) 开销很容易超过复制页面的成本 流媒体方式...
另一个his posts:
非常明显的设置和拆卸成本。我的意思是明显的。这就像跟随页面表一样干净地取消映射。它是用于维护所有映射列表的簿记。这是取消映射后需要的TLB刷新。
页面错误是昂贵的。这就是映射填充的方式,而且速度很慢。
FWIW,这是我工作的最后一次出现,内存映射输入比fread
等人快80%,用于将二进制数据库记录读入专有数据库,在64位Linux上使用~170GB文件。 / p>
答案 1 :(得分:9)
mmap()
可以在流程之间共享。mmap
的内存由内核分配,它始终是对齐的。 答案 2 :(得分:5)
绝对值“更快”不存在。您必须指定约束和环境。
mmap()不按顺序读取。
是什么让你这么想的?如果您确实按顺序访问映射的内存,系统通常会按该顺序获取页面。
mmap()必须从磁盘本身获取,与read()相同
确定,但操作系统确定时间和缓冲区大小
映射区域不是顺序的 - 所以没有DMA(?)。
见上文
mmap
帮助的是没有涉及额外的用户空间缓冲区,“读取”发生在操作系统内核认为合适的地方以及可以优化的块中。这个可能在速度方面具有优势,但首先这只是一个更易于使用的界面。
如果您想了解特定设置(硬件,操作系统,使用模式)的速度,您必须进行测量。