Main Content

内存映射概述

什么是内存映射?

内存映射是将磁盘上某文件的一部分或整个文件映射到应用程序地址空间内某个地址范围的一种机制。然后,应用程序可采用与访问动态内存相同的方法访问磁盘上的文件。与使用 freadfwrite 等函数相比,这会加快文件的读取和写入速度。

内存映射的优势

内存映射的主要优势体现在效率、更快的文件访问速度、能够在应用程序之间共享内存,以及更高效的编码。

更快的文件访问速度

通过内存映射访问文件的速度比使用 freadfwrite 等 I/O 函数访问文件更快。系统使用操作系统内置的虚拟内存功能读取和写入数据,而不必分配数据缓冲区,将数据复制到数据缓冲区,然后取消分配进程所拥有的数据缓冲区。

在先行构造了映射的情况下,MATLAB® 不会从磁盘访问数据。它仅在内存映射的指定部分被访问时才会读取或写入磁盘上的文件,之后便仅读取该特定部分。这可以提高对映射数据的随机访问速度。

效率

将文件映射到内存后,访问文件中的数据时就如同该数据已被读入到应用程序地址空间中的数组。最初,MATLAB 仅为该数组分配地址空间;在您访问映射的区域之前,它不会从文件中实际读取数据。因此,利用内存映射的文件所提供的机制,应用程序无需先将整个文件读入内存,便可访问超大型文件中的数据段。

高效的编码样式

通过 MATLAB 应用程序中的内存映射,您可以使用标准 MATLAB 索引操作来访问文件数据。将文件映射到内存后,您可以使用与读取 MATLAB 工作区中变量所用的相同类型的 MATLAB 语句,来读取该文件的内容。所映射文件的内容就像是当前活动工作区的数组一样。您只需创建此数组的索引,便可在文件中读取或写入所需的数据。因此,您不需要显式调用 freadfwrite 函数。

在 MATLAB 中,如果 x 是内存映射变量,y 是要写入到文件的数据,则只需执行以下命令即可写入到文件:

x.Data = y;

在应用程序之间共享内存

内存映射文件还提供了在应用程序之间共享数据的机制(如下图所示)。实现方法是让各个应用程序映射同一文件的多个部分。您可以使用此功能在 MATLAB 与其他应用程序之间传输大型数据集。

此外,在单一应用程序内,您也可以多次映射文件的同一数据段。

何时使用内存映射

通过将文件映射到内存可以获得多大的优势,这主要取决于该文件的大小和格式、文件中数据的使用方式,以及您所使用的计算机平台。

内存映射何时最有用

内存映射最适合在以下情形中用于二进制文件:

  • 对于需要随机访问一次或多次的大型文件

  • 对于需要一次读入内存然后频繁访问的小文件

  • 对于需要在应用程序之间共享的数据

  • 需要将文件中的数据当作 MATLAB 数组一样进行处理时

何时优势不太明显

以下文件类型无法充分利用内存映射的优势:

  • 需要不适合进行内存映射的自定义读取器的二进制文件,例如 HDF 或 TIFF。描述这些文件中包含的数据可能是一项非常复杂的任务。此外,您也不能直接访问映射段中的数据,而是必须创建数组来保存数据。

  • 需要将映射区内的文本转换为相应类型才能让数据有意义的文本文件或 ASCII 文件。这会占用额外的地址空间。

  • 大小超过几百 MB 的文件,这些文件会消耗大量虚拟地址空间,而 MATLAB 在处理您的程序时需要这些空间。映射如此大的文件可能导致 MATLAB 更频繁地报告内存不足的错误。当 MATLAB 已运行一段时间或 MATLAB 所用的内存变得碎片化时,出现这种情况的可能性更高。

内存映射的最大大小

由于操作系统和 MATLAB 所设的限制,使用单一内存映射实例可以映射的最大数据量为 2 GB(32 位系统)和 256 TB(64 位系统)。如果需要映射的数据量超过此限制,您可以针对文件的不同区域创建单独的映射,也可以将一个映射的窗口移至文件中的不同位置。

字节排序

内存映射仅适用于字节排序方案与操作系统本机字节排序相同的数据。例如,由于 Linus Torvalds 的 Linux® 和 Microsoft® Windows® 系统均使用 little-endian 字节排序,因此在 Linux 系统上创建的数据可以在 Windows 系统上读取。您可以使用 computer 函数来确定当前系统的本机字节排序。