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

时间:2016-06-11 13:41:41

标签: c++ c memory memory-management

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

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

4 个答案:

答案 0 :(得分:9)

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

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

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

答案 1 :(得分:4)

在Linux上有一种机制,请参阅MinimongoError: can't append to array using string field name [estore] [409]"

  

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

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

例如,

/[pid]/pagemap

答案 2 :(得分:4)

我写了page-info library在Linux上做到这一点。它使用隐藏的页面地图文件,因此不会移植到其他操作系统。

某些信息仅限于root用户使用,但您无需root就可以获取有关页面状态的信息(无论它是否在RAM中)。引用自述文件:

  

因此,(作为非root用户)您可以确定页面是否存在,被换出,页面的软脏状态,是否为独占页面以及是否为文件映射,但仅此而已。在较早的内核上,您还可以获取物理帧号(pfn)字段,该字段本质上是页面的物理地址(右移12)。

对于大范围查询,性能并未完全优化,因为它会为每个页面进行单独读取,但是可以很好地接受PR来改善此范围。

答案 3 :(得分:3)

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

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

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