首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Linux MMAP内部

Linux MMAP内部
EN

Stack Overflow用户
提问于 2009-04-15 15:20:12
回答 4查看 11.5K关注 0票数 24

关于Linux系统中的mmap实现,我有几个问题,这些问题似乎没有太多的文档记录:

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

也就是说,当您从mmaped区域读取数据时会发生什么情况?数据是否移动到L1/L2缓存?它是直接从磁盘缓存读取的吗?prefetchnta和类似的ASM指令是否适用于mmaped区域?

实际mmap调用的开销是多少?它是与映射数据量相关,还是与常量相关?

希望有人能对此有所了解。提前谢谢。

EN

回答 4

Stack Overflow用户

发布于 2009-04-15 15:34:09

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

比方说,当你有了1G文件,你映射它,你就会得到一个指向“整个”文件的指针,就像它在内存中一样。

但是,在此阶段,除了为VM中的文件保留页面的实际映射操作外,什么也没有发生。(当然,文件越大,映射操作就越长。)

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

如果你想“预加载”文件的某些部分,只需访问你想要预加载的区域。确保你访问了所有你想要加载的页面,因为虚拟机只会加载你访问的页面。例如,在您的1G文件中,您有一个10MB的“索引”区域,您希望将其映射到其中。最简单的方法是“遍历您的索引”,或者您拥有的任何数据结构,让VM根据需要分页输入数据。或者,如果您“知道”它是文件的“第一个10MB”,并且您的VM的页面大小是4K,那么您可以将mmap指针转换为char指针,并遍历页面。

代码语言:javascript
复制
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;
    }
}

至于L1和L2缓存,mmap与此无关,这都是关于如何访问数据的。

因为您使用的是底层VM系统,所以在mmap'd块中寻址数据的任何东西都可以工作(从汇编开始)。

如果您不更改任何mmap数据,当需要新页时,VM将自动刷新旧页。如果您确实更改了旧页,则VM将为您写回这些页。

票数 31
EN

Stack Overflow用户

发布于 2009-04-15 19:16:37

它与CPU缓存无关;它将它映射到虚拟地址空间,如果随后使用mlock()访问或锁定它,它就会将它物理地带入内存中。CPU缓存它在什么地方或不在什么地方并不是你真正能控制的(至少,不是通过mmap)。

正常情况下,需要接触页面才能映射到页面,但如果执行mlock或mlockall命令,则会产生相同的效果(这些命令通常具有特权)。

至于开销,我真的不知道,你必须衡量它。我的猜测是,不加载页面的mmap()或多或少是一个恒定的时间操作,但是页面越多,引入页面所需的时间就越长。

最近的Linux版本也支持一个标志MAP_POPULATE,它指示mmap立即加载页面(假设只有在可能的情况下)。

票数 4
EN

Stack Overflow用户

发布于 2009-04-30 09:48:44

在回答拉维·普尔松达尔先生的问题时:

只要正确设置了权限,多个进程就可以映射同一个文件。查看mmap手册页,只需传递MAP_SHARED标志(如果需要映射非常大的文件,请改用mmap2 ):

mmap

MAP_SHARED

与映射此对象的所有其他进程共享此映射。存储到区域相当于写入文件。在调用msync(2)或munmap(2)之前,可能不会实际更新文件。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/752192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档