可能重复:
mmap() 与读取块
我听说(在互联网上某处阅读)mmap()
比顺序 IO 更快。它是否正确?如果是,那么为什么它更快?
mmap()
不是按顺序阅读。mmap()
必须像从磁盘本身获取read()
一样- 映射区域不是连续的 - 所以没有 DMA (?)。
那么mmap()
实际上应该比read()
文件慢吗?我上面的哪个假设是错误的?
可能重复:
mmap() 与读取块
我听说(在互联网上某处阅读)mmap()
比顺序 IO 更快。它是否正确?如果是,那么为什么它更快?
mmap()
不是按顺序阅读。mmap()
必须像从磁盘本身获取read()
一样那么mmap()
实际上应该比read()
文件慢吗?我上面的哪个假设是错误的?
我听说(在互联网上某处阅读) mmap() 比顺序 IO 更快。它是否正确?如果是,那么为什么它更快?
可以 - 有利有弊,如下所列。 当您真的有理由关心时,请始终对两者进行基准测试。
除了实际的 IO 效率之外,应用程序代码在需要执行 I/O 时跟踪的方式以及进行数据处理/生成的方式也会产生影响,这有时会极大地影响性能。
1) mmap() 没有按顺序读取。2) mmap() 必须从磁盘本身获取,与 read() 一样 3) 映射区域不是连续的 - 所以没有 DMA(?)。
所以 mmap() 实际上应该比文件中的 read() 慢?我上面的哪个假设是错误的?
1) 错误...mmap()
分配与文件内容相对应的虚拟地址空间区域...每当访问该地址空间中的页面时,会发现物理 RAM 支持虚拟地址,并且相应的磁盘内容错误地进入该 RAM . 因此,从磁盘读取的顺序与访问顺序相匹配。这是一种“惰性”I/O 机制。例如,如果您需要索引一个要从磁盘读取的巨大哈希表,那么mmap
读取文件并开始访问意味着磁盘 I/O 不是按顺序完成的,因此可能会导致整个文件被读入内存之前经过的时间更长,但是当这种情况发生时,查找会成功并且可以进行相关的工作,并且如果文件的某些部分从未真正需要,则不会读取它们(考虑到磁盘和内存页面的粒度,即使使用内存映射,许多操作系统也允许您指定一些关于您计划的性能增强/内存效率提示访问模式,以便他们可以主动提前读取或更积极地释放内存,因为他们知道您不太可能返回它)。
2) 绝对正确
3)“映射区域不连续”含糊不清。内存映射区域在虚拟地址空间中是“连续的”(连续的)。我们已经在上面讨论了磁盘 I/O 是顺序的。或者,你在想别的吗?无论如何,当页面出现故障时,它们确实可能使用 DMA 传输。
此外,内存映射可能优于通常的 I/O 还有其他原因:
这也是mmap
可能变慢的原因 - 请阅读 Linus Torvald 的帖子,其中提到mmap
:
...页表游戏以及错误(甚至只是 TLB 未命中)开销很容易超过以流式传输方式复制页面的成本...
从他的另一个帖子中:
相当明显的安装和拆卸成本。我的意思是引人注目。就像按照页表干净地取消映射所有内容一样。这是维护所有映射列表的簿记。这是取消映射后需要的 TLB 刷新。
页面错误是昂贵的。这就是映射被填充的方式,而且速度很慢。
FWIW,这是我最后一次在工作中出现的情况,在 64 位 Linux 上,内存映射输入比fread
等人将二进制数据库记录读入专有数据库快 80%,文件约为 170GB。
mmap()
可以在进程之间共享。mmap
是由内核分配的,它总是对齐的。绝对意义上的“更快”是不存在的。您必须指定限制条件和情况。
mmap() 没有按顺序读取。
什么让你有那个想法?如果您真的按顺序访问映射内存,系统通常会按该顺序获取页面。
mmap() 必须像 read() 一样从磁盘本身获取
当然,但操作系统确定时间和缓冲区大小
映射区域不是连续的 - 所以没有 DMA (?)。
往上看
有帮助的是mmap
不涉及额外的用户空间缓冲区,“读取”发生在操作系统内核认为合适的地方,并且可以优化的块。这可能是速度上的优势,但首先这只是一个更易于使用的界面。
如果您想了解特定设置(硬件、操作系统、使用模式)的速度,则必须进行测量。