如何在Red Hat Enterprise Linux (x86-64)上计算执行的指令数?

6

我想了解在Red Hat Enterprise Linux上运行程序期间执行了多少个x86-64指令。 我知道可以从valgrind获取此信息,但减速非常明显。 我还知道我们正在使用内置硬件性能计数器的Intel Core 2 Quad CPU(型号Q6700)。 但是我不知道如何从C程序中访问执行的总指令数。


只是好奇,为什么你想知道指令执行的数量?计算周期数似乎更有意义,因为它将慢速指令(例如内存访问)与快速寄存器绑定的指令相加。 - kriss
循环次数包括等待缓存传递数据等停顿时间。因此,它会因运行而异,而指令数量保持恒定。 - Alexander Gorshenev
@kriss:就像Horsh所说的那样——我正在寻找一个稳定且可重复的数字。 - Norman Ramsey
@horsh:这是正确的,但使用一些简单的技巧可以使效果变得非常小(在执行 rdtsc 前调用 cpuid 终止当前指令,运行代码多次并取平均值等)。这完全是关于误差管理,更应用数学,而不是计算机科学。 - kriss
我的担忧是,即使指令数量稳定,如果优化的目标作为一种度量方式是相当错误的,你可以很容易地同时降低指令数量,并使程序实际上变得更慢。例如:通过直接内存访问替换加载然后使用寄存器,指令较少,但代码可能变慢100倍。而且,忽略缓存效果也不是一个好的度量策略。这就是为什么我想知道你想用指令计数做什么?我无法想象任何有用的用途。 - kriss
4个回答

2

libpapi是您需要的库。 AMD和Intel芯片提供指令计数。


2

性能应用编程接口(PAPI)似乎符合您的要求。

网站上可以了解到:

PAPI旨在为大多数主要微处理器中发现的性能计数器硬件的工具设计师和应用程序工程师提供一致的接口和方法。

来自田纳西大学创新计算实验室的博士后研究员Vince Weaver进行了一些与PAPI相关的工作。他在UTK的网页上列出的研究看起来可以提供更多信息。


1

根据您的需求,有几种方法可以实现。如果您只想找出潜在参数的总数,您可以在二进制文件上运行objdump,这将为您提供汇编代码。如果您想要更详细的关于程序运行时实际指令的信息,您可以考虑使用DynamoRIO,它提供了这个功能。它类似于valgrind,但我认为它对性能的影响较小。去年9月,我很快、很容易地用它组合了一个基本的指令计数器。

如果以上方法不适用,您可以尝试查看PAPI,这是一个API,应该可以让您获取处理器上的性能计数器。我从未使用过它,所以无法评价它,但我的一个朋友在6个月前的一个项目中使用了它,并表示他发现它非常有帮助。


1
下面的程序从C中访问循环计数器寄存器(抱歉,非便携式代码,但在gcc中可以正常工作)。这个计数器是用来计算周期的,而不是指令。现代处理器可以在同一条指令上使用多个周期,或者同时执行多条指令。周期通常比指令数量更有趣,但这取决于您的实际目的。
其他性能计数器肯定可以以相同的方式访问(实际上我甚至不知道是否还有其他计数器),但我将不得不查找要使用的实际指令代码。
static __inline__ unsigned long long rdtsc(void)
{
   unsigned long long int x;
   __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
   return x;

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接