Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何知道指针是在物理内存中还是会触发页面错误?_C++_C_Memory_Memory Management - Fatal编程技术网

C++ 如何知道指针是在物理内存中还是会触发页面错误?

C++ 如何知道指针是在物理内存中还是会触发页面错误?,c++,c,memory,memory-management,C++,C,Memory,Memory Management,如果我有一个指针,并且我关心内存访问性能,我可能会检查它上的下一个操作是否会触发页面错误。如果愿意,可以设计一种算法,使其重新排序循环操作,以最小化页面错误 是否有任何可移植(或linux/windows非可移植)的方法来检查特定的内存地址访问是否会触发页面错误?否。没有可移植的方法来检查给定的地址当前是否在物理内存中或在交换文件中被换出。事实上,我认为Linux或Windows都没有提供以不可移植的方式检查这一点的功能。(当然,在Linux中,您可以自己编写) 正如其他人在评论中所说,您还需要

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


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

否。没有可移植的方法来检查给定的地址当前是否在物理内存中或在交换文件中被换出。事实上,我认为Linux或Windows都没有提供以不可移植的方式检查这一点的功能。(当然,在Linux中,您可以自己编写)

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


无论如何,最好的办法是重新排序循环以最小化页面错误(=最大化引用的位置)。

大约十年前,Emery Berger提出了一种支持VM的垃圾收集策略,该策略要求应用程序知道内存中存在哪些页面。出于测试目的,他和他的学生制作了一个内核补丁,该补丁使用实时信号通知应用程序分页事件,从而允许垃圾收集器维护自己的常驻页面数据库。(尽管这看起来像是重复工作,但为了在每次需要时获取信息,它比多次系统调用要高效得多。)

你可以在他的网站上找到关于这项有趣研究的信息


据我所知,在最近的Linux内核中没有实现此修补程序,但它始终可以重新启动。

在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
我写了一篇文章来在Linux上做这件事。它在封面下使用pagemap文件,因此无法移植到其他操作系统

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

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


性能并没有针对查询大范围进行优化,因为它会对每个页面进行单独的读取,但是可以通过PR来改进这一点,这是完全可以接受的

.否,Windows函数不会检查访问指针是否会触发页面错误;它检查指针是否指向映射页面。这两者是不一样的。套用Cody Gray的建议,为什么不实现一个总是提前预取数据的算法呢?这不是处理这种情况最直接的方法吗?(这也不是便携式的,但至少是可能的。)最基本的问题是,如果存在这样的支票,它的承诺将毫无价值。它可能在一纳秒后被取消映射。如果这很重要,那么您只需确保它永远不会被取消映射,Linux中的mlock()和Windows中的VirtualLock()都是如此@hanspassant肯定是正确的,没有任何保证,但这是一种优化,而不是一个先决条件,因此它只需要在大多数情况下是正确的。然而,对状态的轮询比通知的开销要高得多,频繁的内核调用可能比好处更昂贵。另一种方法见我的答案。这真的很有趣!我想知道他们声称的结果是否真的那么令人印象深刻,“通过执行内存中的垃圾收集,BC可以将Java程序的速度提高几个数量级(高达41倍)。”在这种情况下,我看不出linux开发为什么没有将此功能添加到最近的内核中。你认为有什么安全问题吗?不,我不认为有任何安全问题。我对这个想法为什么不被接受有一个看法,但可以说linux团队中没有人有足够的动力来支持这个想法。它加速了使用无效垃圾收集策略的10年Java程序。我不确定这是如何适用于C或C++,或任何非垃圾收集语言,就此事而言。(不是要从答案中拿走;非常有趣的历史信息)。C++:C和C++是垃圾收集语言。“垃圾收集正在模拟一个具有无限内存的计算机。”你的观点仍然有效。“但是,IcStestCt和C++没有真正做到这一点。虚拟内存子系统可能是,但这将是操作系统的一个功能,而不是语言。当然,我理解Raymond所提出的观点,并且之前也说过很多次关于终结器的完全相同的话,但是我认为说“空垃圾收集器”(即没有垃圾收集器)是不合理的是一种垃圾回收器,因此C和C++是垃圾回收的,因为它们有一个空垃圾回收器。这看起来真的很有希望,我想知道在这里保持投票以做出决定的速度会有多快。没有根访问权限这是可以访问的吗?我不确定你是否想使用这个机制来做你想做的事情,我只是为了完整性列出的。您似乎需要成为root用户,即使proc文件似乎属于我,如果我尝试的话