为什么从内存映射文件读取如此之快?

时间:2014-10-19 22:40:15

标签: c++ windows memory-mapped-files

我对内存映射i / o没有多少经验,但在第一次使用它们之后,我惊呆了它们的速度有多快。在我的性能测试中,我发现从内存映射文件读取的速度比通过常规c ++ stdio读取速度快30倍。

我的测试数据是一个3GB的二进制文件,它包含20个大型双精度浮点数组。我的测试程序的结构方式,我称之为外部模块的读取方法,它使用后台的内存映射i / o。每次调用read方法时,此外部模块都会返回一个指针以及指针指向的数据大小。从这个方法返回后,我调用memcpy将返回的缓冲区的内容复制到另一个数组中。由于我正在使用memcpy来复制内存映射文件中的数据,我预计内存映射读取速度并不比普通stdio快得多,但令我惊讶的是它的速度提高了30倍。

为什么从内存映射文件读取如此之快?

PS:我使用的是Windows机器。我对i / o速度进行了基准测试,机器的最大磁盘传输速率约为90 MiB / s

1 个答案:

答案 0 :(得分:13)

IO的OS内核例程,如读或写调用,仍然只是函数。编写这些函数是为了将数据复制到用户空间缓冲区或从用户空间缓冲区复制到内核空间结构,然后复制到设备。当您考虑存在用户缓冲区,IO库缓冲区(例如stdio buf),内核缓冲区,然后是文件时,数据可能会通过3个副本来获取程序和磁盘之间的内容。 IO例程也必须是健壮的,最后,sys调用本身会产生延迟(陷阱到内核,上下文切换,再次唤醒进程)。

当您对内存映射文件时,您正在跳过大部分内容,从而消除了缓冲区副本。通过有效地将文件视为大型虚拟阵列,您可以启用随机访问而无需通过系统调用开销,因此可以降低每个IO的延迟,如果原始代码效率低下(许多小型随机IO调用),则开销也会降低更彻底。

虚拟内存的抽象,多处理操作系统有价格,就是这样。

但是,在某些情况下,您可以通过在知道它会损害性能(例如大型连续写入)的情况下禁用缓冲来改进IO,但除此之外,您实际上无法在不消除内存映射IO的情况下提高内存映射IO的性能操作系统。