Linux MMAP内部

23 linux posix mmap

关于mmapLinux系统中的实现,我有几个问题似乎没有太多记录:

使用时将文件映射到内存时mmap,如何处理预取此类文件中的数据?

也就是当你从mmaped区域读取数据时会发生什么?这些数据是否已移至L1/L2缓存?它是直接从磁盘缓存中读取的吗?prefetchnta相似的ASM指令是否适用于mmaped区域?

实际mmap通话的开销是多少?它是相对于映射数据量还是常量?

希望有人对此有所了解.提前致谢.

Wil*_*ung 29

mmap基本上是对虚拟内存子系统的编程访问.

当你有1G文件,并且你对它进行mmap时,你会得到一个指向"整个"文件的指针,就好像它在内存中一样.

但是,在此阶段没有发生任何事情,除了为VM中的文件保留页面的实际映射操作.(文件越大,映射操作的时间就越长.)

为了从文件中开始读取数据,您只需通过mmap调用中返回的指针访问它.

如果您希望"预加载"文件的某些部分,只需访问您要预加载的区域即可.确保您访问了要加载的所有页面,因为VM只会加载您访问的页面.例如,在你的1G文件中,你有一个10MB的"索引"区域,你想要映射.最简单的方法是"走你的索引",或者你拥有的任何数据结构,让VM页面必要时在数据中.或者,如果您"知道"它是文件的"前10MB",并且您的VM的页面大小是4K,那么您可以将mmap指针强制转换为char指针,然后只需遍历页面.

void load_mmap(char *mmapPtr) {
    // We'll load 10MB of data from mmap
    int offset = 0;
    for(int offset = 0; offset < 10 * 1024 * 1024; offset += 4 * 1024) {
        char *p = mmapPtr + offset;
        // deref pointer to force mmap load
        char c = *p;
    }
}
Run Code Online (Sandbox Code Playgroud)

至于L1和L2缓存,mmap与此无关,这与你如何访问数据有关.

由于您正在使用底层VM系统,因此在mmap'd块中处理数据的任何内容都将起作用(从汇编开始).

如果您不更改任何mmap数据,VM将在需要新页面时自动清除旧页面如果您确实更改了它们,则VM将为您写回这些页面.

  • char"c =*p"不会被优化掉吗?应该宣布挥发性吗? (8认同)