我想查看我的程序正在访问哪些页面。现在,一种方法是使用mprotect
和SIGSEGV
处理程序来记下正在访问的页面。但是,这涉及为我感兴趣的所有存储器页面设置保护位的开销。
第二种方法是在开始时使翻译后备缓冲区(TLB)无效,然后记下未命中。每次未命中时,我都会记下寻址的内存页面,因此请记下来。现在的问题是如何处理Linux程序的用户空间中的TLB未命中。
如果您知道甚至比TLB未命中或 mprotect 更快的方法来记下脏的内存页面,请告诉我。另外,我只想要一个x86的解决方案。
答案 0 :(得分:7)
我想查看我的程序正在访问哪些页面。
您可以模拟CPU并获取此数据。变体:
但是,这涉及为所有存储器页设置保护位的开销
这个开销太大了吗?
现在的问题是如何处理Linux程序的用户空间中的TLB未命中。
你无法在内核空间(在x86和许多其他流行的平台上)处理未命中或用户空间。这是因为大多数平台manages TLB misses in hardware:。 MMU(CPU /芯片组的一部分)将在页表上执行操作,并将透明地获取物理地址。 仅当设置了某些位或未映射地址区域时,才会生成页面错误中断并将其传送到内核。
此外,似乎无法在现代CPU(but 386DX was able to to this)
中转储TLB您可以尝试通过引入的延迟来检测TLB未命中。但是这种延迟可以通过TLB查找的无序启动来隐藏。
此外,大多数硬件事件(内存访问,tlb访问,tlb命中,tlb未命中)都由硬件性能监控计算(这部分CPU由Vtune,CodeAnalyst和oprofile使用)。不幸的是,这只是事件的全局计数器,您不能同时激活2-4个以上的事件。好消息是,当达到一些计数时,你可以将perfmon计数器设置为中断。然后,您将获得(通过中断)指令的地址($ eip),其中已达到计数。所以,你可以找到这个硬件的TLB-miss-heavy热点(它在每个现代的x86 cpu中;无论是intel还是amd)。
答案 1 :(得分:6)
TLB对用户空间程序是透明的,最多可以通过一些性能计数器(没有地址)来计算TLB未命中数。
答案 2 :(得分:-1)
查看/ proc / PID / maps文件以查找您的进程。根据{{3}}中的文档,/ proc / PID / maps指定每个进程的内存映射。此地图将告诉您“我的程序正在访问哪些页面”。但是,看起来您想知道哪些是脏页。虽然我不确定如何找到脏页的确切页面,但通过查看私有脏域和共享脏域,可以找到有多少页面是脏的/ proc / PID / smaps并将其除以pagesize。请注意,此方法非常快。我相信通过定期轮询/ proc / PID / map可以获得哪些页面是脏的近似概念。