以另一种方式提出问题,您是否可以确认当您mmap()实际访问已存在于页面缓存中的确切物理页面的文件时?mmap是否直接访问页面缓存或页面缓存的副本?
我问,因为我正在测试一台内存为1TB的192核心机器上,在测试之前预先缓存到页面缓存中的400GB数据文件上(只需删除缓存,然后执行md5sum在文件上)。假设它们都(基本上)返回相同的内存区域(或者可能是相同的内存区域,但以某种方式映射多次),我最初分别有192个线程分别映射文件。因此,我假设两个使用两个不同映射到同一文件的线程都可以直接访问相同的页面。 (让我们忽略NUMA在这个例子中,虽然他们显然是在更高的线程数量显著。)
然而,在实践中,我发现性能会得到可怕在更高线数时,每个线程分别mmapped文件。当我们删除它,而只是做了一个传入线程的mmap(所有线程都直接访问同一个内存区域),那么性能会大大提高。
这一切都很棒,但我试图找出原因。如果实际上映射文件只是授予对现有页面缓存的直接访问权限,那么我认为它应该映射多少次无关紧要 - 它应该全部放在同一个地方。
但是考虑到有这样的性能成本,在我看来,实际上每个mmap都是独立冗余的(可能是通过从页面缓存复制,或者可能通过从磁盘再次读取)。
你可以评论为什么我看到共享访问同一内存之间的这种不同的性能,而不是映射相同的文件?
谢谢,我感谢您的帮助!
这是一个很好的问题。我不认为我能够回答,但提供一些建议。 1 /为什么不介绍它? perf应该能够很容易地告诉你瓶颈的位置(我希望)。我的猜测是,你打到mmap(小)的开销,但在192线程,它不会扩展。另外,你有没有尝试使用巨大的页面? – Aissen
因为所有有趣的东西都发生在内核的深处,所以配置文件很棘手。就我的应用程序所知,它只是访问内存 - 但是在内存映射,虚拟内存,页面缓存,L3缓存和NUMA节点之间,还有很多移动部件需要注意。这就是说,我同意有更多的工作要做,以解决这个问题,但我希望有一个比我更熟悉内核知识的人可以给出一些建议,至少在*理论中应该发生什么,就像在实践中指导我的测试。 – quinthar
是的,但通常perf会知道内核在哪里花费时间,如果你有正确的符号附加。关于你的问题,我不知道问题的根源是什么。您是否尝试在较小的机器上重现它? – Aissen