我一直在寻找一种方法来记录Linux中进程/执行的所有内存访问。我知道之前有关此主题的问题就像这样
Logging memory access footprint of whole system in Linux
但我想知道是否有任何非仪器工具可以执行此活动。我没有为此目的寻找QEMU / VALGRIND ,因为它会有点慢,我希望尽可能少的开销。
为了这个目的,我查看了perf mem
和像cpu/mem-loads/pp
这样的PEBS事件,但我发现它们只会收集采样数据,而我实际上想要所有内存访问的跟踪而不进行任何采样。
我想知道是否有可能通过使用像QEMU这样的工具来收集所有内存访问而不会浪费过多的开销。是否有可能仅使用PERF但没有样本以便我获得所有内存访问数据?
我还缺少其他任何工具吗?还是给我所有内存访问数据的任何其他策略?
答案 0 :(得分:1)
只是不可能两者都有尽可能快的Spec运行和在此运行中跟踪的所有内存访问(或缓存未命中)(使用系统内跟踪器)。做一个运行时间和其他运行(更长,更慢),甚至重新编译二进制文件进行内存访问跟踪。
你可以从短而简单的程序开始(不是最近的SpecCPU的ref输入,或者你的大程序中的十亿内存访问)和使用perf
linux工具(perf_events)查找记录到所有内存请求的内存请求的可接受比率。有perf mem
工具或您可以尝试一些启用PEBS的内存子系统事件。通过将:p
和:pp
后缀添加到perf事件说明符perf record -e event:pp
来启用PEBS,其中event是PEBS事件之一。同时尝试pmu-tools ocperf.py以便更轻松地进行英特尔事件名称编码并查找启用PEBS的事件。
尝试在内存性能测试中找到具有不同记录比率(1%/ 10%/ 50%)的实际(最大)开销。检查[Roofline model] Arithmetic Intensity scale左侧部分内存记录开销的最坏情况(https://crd.lbl.gov/departments/computer-science/PAR/research/roofline/。此部分的典型测试是:STREAM(BLAS1),RandomAccess(GUPS)和memlat几乎是SpMV ;许多实际任务通常不会留在规模上:
您是否要跟踪每个加载/存储命令,或者您只想记录错过所有(某些)缓存的请求并将其发送到PC的主RAM内存(到L3)?
为什么不需要开销和所有内存访问?这是不可能的,因为每个存储器访问都有几个字节的跟踪(存储器地址,有时是:指令地址)要记录到同一个存储器中。因此,启用内存跟踪(超过10%或内存访问跟踪)显然会限制可用内存带宽,程序运行速度会变慢。甚至可以记录1%的跟踪,但它的影响(开销)更小。
您的CPU E5-2620 v4是Broadwell-EP 14nm,因此它可能还有一些英特尔PT的早期版本:https://software.intel.com/en-us/blogs/2013/09/18/processor-tracing https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/intel-pt.txt https://github.com/01org/processor-trace,特别是Andi Kleen&#39} pt上的博客:http://halobates.de/blog/p/410"英特尔处理器跟踪的备忘单与Linux perf和gdb"
硬件中的PT支持:Broadwell(第5代Core,Xeon v4)更多开销。没有精细的时间。
PS:研究SpecCPU进行内存访问的学者使用内存访问转储/跟踪,并且转储生成缓慢:
仪表开销:仪表涉及 动态地或静态地将额外的代码注入到 目标应用。附加代码会导致 申请花费额外的时间来执行原件 应用程序...另外,对于多线程 应用程序,仪器可以修改排序 在不同线程之间执行的指令 应用。因此,IDS具有多线程 应用程序缺乏一些保真度
缺乏猜测:仪器只能观察到 在正确的执行路径上执行的指令。如 结果,IDS可能无法支持错误路径...
仅用户级流量:当前二进制检测 工具仅支持用户级检测。从而, 内核密集型应用程序不适合 用户级IDS。