基准测试 - 如何计算发送到 CPU 的指令数以查找消耗的 MIPS

Mic*_*kan 4 cpu performance benchmarking assembly profiling

假设我有一个软件,并且想要使用黑盒方法研究其行为。我有一个 3.0GHz CPU,有 2 个插槽和 4 个核心。如您所知,为了找出每秒指令数 (IPS),我们必须使用以下公式:

IPS = sockets*(cores/sockets)*clock*(instructions/cycle)
Run Code Online (Sandbox Code Playgroud)

首先,我想找到我的特定算法每个周期的指令数。然后我意识到使用块盒方法几乎不可能计算它,我需要对算法进行深入分析。

但现在,我有两个问题:无论我的机器上运行什么类型的软件及其CPU使用率,有没有办法计算每秒发送到CPU的指令数(每秒百万条指令(MIPS))?是否有可能找到指令集的类型(添加、比较、输入、跳转等)?

任何脚本或工具推荐都将受到赞赏(任何语言)。

Pet*_*des 5

perf stat --all-user ./my_programLinux上的CPU会使用CPU性能计数器来记录它运行了多少个用户空间指令,以及它花费了多少个核心时钟周期。它使用了多少 CPU 时间,并将为您计算每个核心时钟周期的平均指令,例如

3,496,129,612      instructions:u            #    2.61  insn per cycle
Run Code Online (Sandbox Code Playgroud)

它为你计算IPC;这通常比每秒指令数更有趣uops不过,就您距离最大化前端的程度而言,每个时钟通常更有趣。 您可以从和手动计算 MIPS 。instructionstask-clock 对于大多数其他事件,perf 以每秒的速率打印一条评论。

(如果您不使用--all-user,则可以使用perf stat -e task-clock:u,instructions:u, ... 让这些特定事件仅在用户空间中计数,而其他事件可以始终计数,包括内部中断处理程序和系统调用。)

但是,请参阅如何使用 perf stat 计算 MIPS,了解更多详细信息,instructions / task-clock了解instructions / elapsed_time是否确实需要跨核心的总或平均 MIPS,以及是否计算睡眠。


有关在静态可执行文件中的小型微基准循环上使用它的示例输出,请参阅Can x86's MOV确实是“免费的”吗?为什么我根本无法重现这个?

如何在运行时获取实时信息

您的意思是从程序内部仅分析其中的一部分吗?有一个 perf API,你可以做perf_event_open一些事情。或者使用不同的库直接访问硬件性能计数器。

perf stat非常适合对已隔离到仅运行热循环一秒钟左右的独立程序中的循环进行微基准测试。

或者也许你的意思是别的。 将每 1000 毫秒(1 秒)打印一次计数器值,以查看程序行为如何随着您想要的时间窗口(低至 10 毫秒间隔)perf stat -I 1000 ... ./a.out实时变化。

sudo perf top是系统范围的,有点像 Unixtop

还需要perf record --timestamp记录每个事件样本的时间戳。 perf report -D可能与此一起有用。参见http://www.brendangregg.com/perf.html,他提到了一些关于-T--timestamp)的内容。我还没有真正使用过这个;我主要隔离单个循环,将其调整为可以在perf stat.


是否有可能找到指令集的类型(添加、比较、输入、跳转等)?

Intel x86 CPU 至少有一个用于分支指令的计数器,但除了 FP 指令之外,其他类型没有区别。这对于大多数具有性能计数器的架构来说可能很常见。

对于 Intel CPU,有ocperf.pyperf ,它是一个带有符号名称的包装器,用于更多微体系结构事件。(更新:plainperf现在知道大多数特定于 uarch 的计数器的名称,因此您不再需要了ocperf.py。)

perf stat -e task_clock,cycles,instructions,fp_arith_inst_retired.128b_packed_single,fp_arith_inst_retired.scalar_double,uops_executed.x87 ./my_program

它并不是为了告诉您正在运行哪些指令,您已经可以通过跟踪执行来判断。大多数指令都是完全流水线化的,因此有趣的是哪些端口的压力最大。例外是除法/平方根单元:有一个计数器arith.divider_active:“除法单元忙于执行除法或平方根运算时的周期。考虑整数和浮点运算”。分频器没有完全流水线化,因此即使没有旧的 uops 准备在端口 0 上执行,新的divps或也不能总是启动。( http://agner.org/optimize/ )sqrtps

相关:linux perf:如何解释和查找热点以用于perf识别热点。特别是使用自上而下的分析,您可以perf对调用堆栈进行采样,以查看哪些函数进行了大量昂贵的子调用。(我提到这一点是为了以防万一这是您真正想知道的,而不是指令组合。)

有关的:


为了获得精确的动态指令计数,如果您使用的是 x86,则可以使用 Intel PIN 等检测工具https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool

perf stat硬件的计数instructions:u甚至也应该或多或少准确,并且实际上在执行相同工作的同一程序的运行中非常可重复。

在最新的 Intel CPU 上,硬件支持记录条件/间接分支的走向,因此您可以准确地重建哪些指令按顺序运行,假设没有自修改代码并且您仍然可以读取任何 JIT 缓冲区。 英特尔PT


抱歉,我不知道 AMD CPU 上的等效项是什么。