1

我在以下链接中阅读了有关内存映射的信息
https://en.wikipedia.org/wiki/Memory-mapped_file
http://en.wikipedia.org/wiki/Memory-mapped_I/O

它用于映射文件和设备。它说文件映射的优点是与直接从磁盘/闪存读取相比更快。但是为什么要花费相同的时间将数据从磁盘/闪存复制到虚拟内存?

但无法找到使用内存映射 I/O 的优势。与直接阅读相比有什么好处?

由于内存映射在虚拟内存中有特定的区域,它位于堆内存之上和堆栈空间之下。因为我们可以控制进程的堆和堆栈空间。如何控制(即增加/减少)虚拟内存中的内存映射区域?

4

2 回答 2

2

首先要了解堆和栈本身是由内存映射组成的。每个用户态进程都有一个内存映射表,这就是它与内核内存管理器交互的方式。内存映射具有不同的配置和功能。请参阅mmap(2)手册页以获取设置列表。

使用文件支持的 mmap,内核以高度优化的方式以页面大小(4096 字节)为单位管理文件的缓存。

如果您要按顺序读取文件,那么内存映射没有任何优势。

如果您打算以随机访问的方式读取文件,那么内存映射文件可能会更高性能(通常是这样),因为内核会自动为您应用缓存策略,大多数平台都支持 CPU。

粗略地说,文件被划分为 4096 字节的块(页)。当从内存中读取一个字节(使用存储在内存映射中的变量)时,CPU 会计算它在哪个块(页)中,然后查询它的页表以查看该页是否在物理内存中。如果不是,则会发生页面错误,并将页面从文件加载到物理内存(全部 4096 字节)。然后将访问转换为物理内存访问。

通过以这种方式按需加载文件,对于许多访问模式,它会更快。

将文件作为内存区域访问(使用指针算法),然后通过文件接口(seek)也更方便。

于 2013-07-19T02:04:52.923 回答
1

但是为什么要花费相同的时间将数据从磁盘/闪存复制到虚拟内存?

使用 read() 系统调用的传统文件 io 有两个数据副本。+ 一份从磁盘复制到缓冲区缓存 + 一份从缓冲区缓存复制到 read() 调用提供的用户缓冲区。

使用 mmap() 我们可以直接将数据复制到用户缓冲区和页面缓存中,这是 mmap() 的缓冲区缓存版本。

但是,mmap() 和 read()/write() 模型各有利弊,大多数现代操作系统都将页面缓存和缓冲区缓存统一为一个统一的缓存。所以,不确定我们在两者之间有多少性能优势......

read() 调用 => 系统调用。因此,除了上述之外,我们还缓冲了读取,即 fread(),我们在 libc 的流中缓存了一些文件数据。这降低了系统调用更多数据的成本,但对于新数据,我们需要一个系统调用。对于 mmap 区域,访问新数据的成本是故障与系统调用转换的成本。IO 成本当然与您暗示的相同。

于 2013-07-19T05:44:43.940 回答