如何记录每个内存访问的带时间戳的跟踪?

问题描述 投票:2回答:3

有没有办法记录给定程序的每个内存访问,包括时间戳。 perf可以用来做那件事吗?

linux memory cpu-architecture perf
3个回答
3
投票

如果您使用英特尔,我认为其他答案中提到的英特尔PT功能与后期处理和分析相结合,最有可能为您提供高速(即性能单位数回归)。

如果您不关心性能,可以使用任意数量的二进制检测框架来获取此信息。例如,valgrind框架有一个cachegrind工具,它捕获每个内存访问并使用它们来估计基于理想化缓存模型的缓存行为。

您几乎可以修改cachegrind工具以吐出您所访问的访问列表以及时间戳。当然,问题在于cachegrind可能运行的速度比本机应用程序慢10倍,因此您的时间戳将“伸出”并失真(即,因为程序的各个部分可能具有不同的检测开销)。

这对您的申请是否重要取决于您。

Valgrind的优点在于它不依赖于任何特定的硬件并且可以在不同的硬件架构中运行。它可能比基于英特尔PT的分析工作更容易 - 虽然我不是百分之百确定,因为我自己也尝试过。

如果您在录制时并不关心实际过程的总运行时间,但需要大多数准确的时序数字,您还可以考虑在CPU模拟器下运行您的过程,例如Peter在评论中提到的Sniper x86 simulatorgem5

描述CMP $ im工具的This site可能对您非常有用。它可以使用英特尔的PIN technology产生一系列访问,@ Leee在下面的评论中也提到过。我建议您查看该网站链接的作者相关论文。


2
投票

IntelPT将记录时间戳,并使用将记录到硬件中的各种数据包跟踪正在运行的应用程序的控制流信息。然后来自IntelPT的这些信息可以作为decoders的输入,这将有助于获得反汇编的指令。而且,IntelPT也被整合到perf中。

您可以将perf与IntelPT一起用作以下事件 -

perf record -e intel_pt//[uk]  /bin/ls

[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.384 MB perf.data ]

但是,我建议使用PEBS(基于精确事件的采样)。 PEBS(基于精确事件的采样)是一个可用于事件子集的功能,它允许硬件收集非常接近配置事件溢出的确切时间的附加信息。您也可以将PEBS与perf一起使用。

假设您要记录与内存负载相关的信息。 PEBS计数器将初始化为某个最大值(实际上是采样周期)。然后,每个内存负载将这些计数器减1。一旦计数器达到零,PEBS硬件就会启动。然后,下一个内存加载事件将导致PEBS记录写入PEBS缓冲区。一旦发生这种情况,PEBS计数器将自动重置为其先前的值。这就是如何,样本周期为2将导致系统在间隔2后记录内存负载。

无论如何,使用PEBS的一个好处是它非常精确,可以从它的工作方式中猜到。与大多数其他记录机制不同,您必须等待软件中断来记录事件详细信息,并且记录会在数百个CPU周期后发生。

将PENS与qazxsw poi结合使用来记录这样的内存负载 -

perf

r81d0:pp表示数字形式的退役指令中的事件存储器加载。在某些情况下,某些CPU架构不支持某些事件,并且一个人被迫使用这样的数字事件。

然而,正如Peter所说,并且正如许多其他perf record -e r81d0:pp -c 1 -d <application_name> <application_params> questions所强调的那样,在没有外部硬件机制和/或导致运行时的显着开销的情况下,绝对不可能记录100%的内存加载或内存存储地址。

想了解PEBS吗? answers将是你最好的朋友。


2
投票

我能想到的最接近的硬件功能是Intel's software developer manual(处理器跟踪),它可以记录每个(采用?)分支的时间戳,因此您可以重建执行到包含负载的块。我没有用过pt,我不确定Intel PT是否可以使用它,或者你是否需要不同的程序。

(不完全是“基本块”,因为在执行其他地方的分支目标时没有记录)

这可能仅在发出加载指令时,而不是在无序执行实际运行它们或数据从内存/ L1d缓存到达时。

我认为任何现有的x86芯片都不能为每次加载完成记录准确的时间戳;这将是太多的数据。


如果您正在寻找内存热点,我建议使用perf或类似计数器进行分析,以查找在不同级别的缓存中经常错过的负载。存在一些存储事件,但主要用于加载,因为CPU必须等待加载数据才能使用它。

也许还有perf record -e mem_load_retired.l3_miss,mem_load_retired.l2_miss或其他TLB-miss事件。

还有一个针对dtlb_load_misses.miss_causes_a_walk的事件,它会在停顿时对每个周期进行计数,以查找OoO exec无法隐藏缓存未命中延迟的情况。

使用cycle_activity.stalls_l3_miss查看perf list所知道的事件。如果你的perf是旧的,你可能需要perf包装。 ocperf.py

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.