处理TLB未命中

Met*_*est 4 c linux x86 caching tlb

我想查看我的程序正在访问哪些页面.现在,一个方法是使用mprotectSIGSEGV处理程序,记下其正在访问的网页.但是,这涉及为我感兴趣的所有存储器页面设置保护位的开销.

想到的第二种方法是在开始时使翻译后备缓冲区(TLB)无效,然后记下未命中.每次未命中时,我都会记下寻址的内存页面,因此请记下来.现在的问题是如何处理Linux程序的用户空间中的TLB未命中.

如果你知道甚至比TLB错过或阻止记下脏的内存页面更快的方法,请告诉我.另外,我只想要一个x86的解决方案.

osg*_*sgx 7

我想查看我的程序正在访问哪些页面.

您可以模拟CPU并获取此数据.变种:

  • 1)valgrind - 用户空间二进制文件的动态翻译器,具有良好的仪器支持.尝试使用cachegrind工具 - 它甚至可以模拟L1/L2缓存; 您也可以尝试构建新工具来记录所有内存访问(例如,页面粒度)
  • 2)qemu - 动态转换器,包括系统范围和全过程模式.据我所知,原来的qemu没有仪器
  • 3)bochs - 系统范围的CPU仿真器(非常慢).您可以轻松破解"内存访问"代码以获取内存日志.
  • 4)PTLsim - www.ptlsim.org/papers/PTLsim-ISPASS-2007.pdf

但是,这涉及为所有存储器页设置保护位的开销

这个开销太大了吗?

现在的问题是如何处理Linux程序的用户空间中的TLB未命中.

你无法在内核空间(在x86和许多其他流行的平台上)处理未命中或用户空间.这是因为大多数平台管理硬件中的 TLB未命中:.MMU(CPU /芯片组的一部分)将在页表上执行操作,并将透明地获取物理地址.仅当设置了某些位或未映射地址区域时,才会生成页面错误中断并将其传送到内核.

此外,似乎没有办法在现代CPU中转储TLB(但386DX能够达到此目的)

您可以尝试通过引入的延迟来检测TLB未命中.但是这种延迟可以通过TLB查找的无序启动来隐藏.

此外,大多数硬件事件(内存访问,tlb访问,tlb命中,tlb未命中)都由硬件性能监视计算(这部分CPU由Vtune,CodeAnalyst和oprofile使用).不幸的是,这只是事件的全局计数器,您不能同时激活2-4个以上的事件.好消息是,当达到一些计数时,你可以将perfmon计数器设置为中断.然后,您将获得(通过中断)指令的地址($ eip),其中已达到计数.所以,你可以找到这个硬件的TLB-miss-heavy热点(它在每个现代的x86 cpu中;无论是intel还是amd).


ado*_*yan 6

TLB对用户空间程序是透明的,最多可以通过某些性能计数器(没有地址)来计算TLB未命中数.