如何知道指针是在物理内存中还是会触发Page Fault?

问题描述 投票:9回答:4

如果我有一个指针并且我关心内存访问性能,我可能会检查它上面的下一个操作是否会触发页面错误。如果愿意,可以设计一种算法,以便重新排序循环操作以最小化页面错误。

是否有任何便携式(或linux / windows非便携式)方式来检查特定的内存地址,访问是否会触发页面错误?

c++ c memory memory-management
4个回答
4
投票

我写了page-info library在Linux上这样做。它使用封面下的页面映射文件,因此无法移植到其他操作系统。

某些信息仅限于root用户,但您应该能够获得有关页面存在的信息(无论是否在RAM中)而不是root用户。引自README:

因此[作为非root用户],您可以确定页面是否存在,换出,其软脏状态,是否是独占的以及是否是文件映射,但不是更多。在较旧的内核上,您还可以获取物理帧编号(pfn)字段,该字段实际上是页面的物理地址(右移12)。

对于查询大范围而言,性能并未完全优化,因为它为每个页面单独读取,但是可以非常接受用于改进这一点的PR。


9
投票

大约十年前,Emery Berger提出了一种VM感知垃圾收集策略,该策略要求应用程序知道内存中存在哪些页面。出于测试目的,他和他的学生制作了一个内核补丁,它使用实时信号通知了分页事件的应用,允许垃圾收集器维护自己的驻留页面数据库。 (虽然这似乎是重复工作,但它比多次系统调用更有效,以便在每次需要时获取信息。)

你可以在他的research page上找到有关这项有趣研究的信息。

据我所知,最近的Linux内核没有实现这个补丁的实现,但它总是可以复活它。


4
投票

在Linux上有一个机制,请参阅man proc

/[pid]/pagemap此文件显示每个进程的虚拟页面到物理页面框架或交换区域的映射。它包含每个虚拟页面的一个64位值,其位设置如下:

  • 63如果设置,页面将出现在RAM中。
  • 62如果设置,则页面位于交换空间中
  • ...

例如,

$ sudo hexdump -e '/0 "%08_ax "' -e '/8 "%016X" "\n"' /proc/self/pagemap 
00000000 0600000000000000
*
00002000 A6000000000032FE
00002008 A60000000007F3A6
00002010 A600000000094560
00002018 A60000000008D0C0
00002020 A60000000009EBE6
00002028 A6000000000C8E87

3
投票

没有。没有可移植的方法来检查给定地址当前是在物理内存中还是在交换文件中换出。事实上,我不认为Linux或Windows提供了以非便携方式检查这一点的工具。 (当然,在Linux中你可以自己编写)。

正如其他人在评论中所说,您还想检查数据是否在缓存中(从物理内存访问比缓存慢得多)。

最好的办法是重新排序循环,以最大限度地减少页面错误(==最大化参考位置)。

© www.soinside.com 2019 - 2024. All rights reserved.