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

Why is reading from a memory mapped file so fast?

本文关键字:读取 速度 如此之 文件 内存 映射 为什么      更新时间:2023-10-16

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

我的测试数据是一个3GB的二进制文件,它包含20个大的双精度浮点数组。按照我的测试程序的结构,我调用了一个外部模块的读取方法,该方法在后台使用内存映射的I/o。每次我调用read方法时,这个外部模块都会返回一个指针和指针指向的数据大小。从这个方法返回后,我调用memcpy将返回的缓冲区的内容复制到另一个数组中。由于我正在执行memcpy从内存映射文件中复制数据,我预计内存映射读取不会比普通stdio快很多,但我很惊讶它快了30倍。

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

附言:我用的是Windows电脑。我以我的I/o速度为基准,我的机器的最大磁盘传输速率约为90 MiB/s

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

当您对一个文件进行内存映射时,您会跳过其中的大部分内容,从而消除缓冲区副本。通过将文件有效地视为一个大的虚拟阵列,您可以在不需要系统调用开销的情况下实现随机访问,从而降低每个IO的延迟,如果原始代码效率低下(许多小的随机IO调用),则开销会大大降低。

虚拟内存、多处理操作系统的抽象是有代价的,这就是它

然而,在某些情况下,您可以通过在知道缓冲会影响性能的情况下禁用缓冲来改善IO,例如大型连续写入,但除此之外,如果不完全消除操作系统,您真的无法提高内存映射IO的性能。