基准测试 - 如何计算发送到 CPU 的指令数以查找消耗的 MIPS
Benchmarking - How to count number of instructions sent to CPU to find consumed MIPS
假设我有一个软件,想使用 black-box 方法研究它的行为。我有一个 3.0GHz CPU,带有 2 个插槽和 4 个内核。如您所知,为了找出每秒指令数 (IPS),我们必须使用以下公式:
IPS = sockets*(cores/sockets)*clock*(instructions/cycle)
起初,我想为我的特定算法找到每个周期的指令数。然后我意识到用block-box的方法来计算它几乎是不可能的,我需要对算法做深入的分析。
但是现在,我有两个问题:无论我的机器上 运行 是什么类型的软件及其 cpu 用法,有没有办法计算每秒发送到的指令数CPU(每秒百万条指令 (MIPS))?是否可以找到指令集的类型(添加、比较、输入、跳转等)?
如有任何脚本或工具推荐(任何语言),我们将不胜感激。
Linux 上的 perf stat --all-user ./my_program
将使用 CPU 性能计数器来记录它 运行 有多少用户-space 指令,以及有多少核心时钟周期花了。以及它使用了多少 CPU 时间,并将为您计算每个核心时钟周期的平均指令数,例如
3,496,129,612 instructions:u # 2.61 insn per cycle
它为你计算IPC;这通常比每 秒 的指令更有趣。 uops
每个时钟通常更有趣,但就您离最大化前端的接近程度而言。 您可以根据 instructions
和 task-clock
手动计算 MIPS。 对于大多数其他事件,perf 以每秒速率打印注释。
(如果你不使用 --all-user
,你可以使用 perf stat -e task-clock:u,instructions:u
,...让这些特定事件仅在 user-space 中计数,而其他事件可以总是计数,包括内部中断处理程序和系统调用。)
但如果您确实想要跨内核的总 MIPS 或平均 MIPS,以及是否计算睡眠,请参阅 了解有关 instructions / task-clock
与 instructions / elapsed_time
的更多详细信息。
有关在静态可执行文件中的微型基准测试循环中使用它的示例输出,请参阅
How can I get real-time information at run-time
你的意思是从程序内部,只分析它的一部分吗?有一个 perf API,你可以在其中执行 perf_event_open
或其他操作。或者使用不同的库直接访问硬件性能计数器。
perf stat
非常适合对已隔离到独立程序中的循环进行微基准测试,该程序只是 运行 热循环一秒钟左右。
或者您可能有其他意思。 perf stat -I 1000 ... ./a.out
将每 1000 毫秒(1 秒)打印一次计数器值,以查看程序行为如何实时变化 以及您想要的任何时间 window(低至 10 毫秒)间隔)。
sudo perf top
是系统范围的,有点像 Unix top
还有 perf record --timestamp
记录每个事件样本的时间戳。 perf report -D
可能与此一起有用。看到http://www.brendangregg.com/perf.html,他提到了一些关于-T
(--timestamp
)的事情。我还没有真正使用过这个;我主要隔离单个循环 我正在调整为静态可执行文件 我可以 运行 在 perf stat
.
下
And is it possible to find the type of instruction set (add, compare, in, jump, etc)?
Intel x86 CPUs 至少有一个 b运行ch 指令的计数器,但其他类型没有区别,除了 FP 指令。这对于大多数具有性能计数器的架构来说可能很常见。
对于英特尔 CPUs,有 ocperf.py,perf
的包装器,带有更多微体系结构事件的符号名称。 (更新:plain perf
现在知道大多数 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
它不是为了告诉你什么指令是运行宁,你已经可以从跟踪执行中知道。大多数指令都是完全流水线的,所以有趣的是哪些端口的压力最大。例外是 divide/sqrt 单元:arith.divider_active
有一个计数器:“除法单元忙于执行除法或平方根运算时的循环数。考虑整数和浮点运算”。分频器没有完全流水线化,所以即使没有旧的 uops 准备好在端口 0 上执行,新的 divps
或 sqrtps
也不能总是启动。 (http://agner.org/optimize/)
相关:linux perf: how to interpret and find hotspots 使用 perf
识别热点。特别是使用自上而下的分析,您可以 perf
对调用堆栈进行采样,以查看哪些函数进行了大量昂贵的子调用。 (我提到这个是为了防止你真正想知道,而不是指令组合。)
相关:
- How do I determine the number of x86 machine instructions executed in a C program?
对于精确的动态指令计数,如果您使用的是 x86,则可以使用像 Intel PIN 这样的检测工具。 https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool.
perf stat
对 instructions:u
硬件的计数甚至应该或多或少是准确的,并且实际上在执行相同工作的同一程序的 运行 之间非常可重复。
在最近的 Intel CPUs 上,硬件支持记录条件/间接 b运行ches 的路径,因此您可以准确地重建哪些指令 运行 的顺序,假设没有自修改代码,并且您仍然可以读取任何 JIT 缓冲区。 Intel PT.
抱歉,我不知道 AMD CPUs 上的等效项是什么。
假设我有一个软件,想使用 black-box 方法研究它的行为。我有一个 3.0GHz CPU,带有 2 个插槽和 4 个内核。如您所知,为了找出每秒指令数 (IPS),我们必须使用以下公式:
IPS = sockets*(cores/sockets)*clock*(instructions/cycle)
起初,我想为我的特定算法找到每个周期的指令数。然后我意识到用block-box的方法来计算它几乎是不可能的,我需要对算法做深入的分析。
但是现在,我有两个问题:无论我的机器上 运行 是什么类型的软件及其 cpu 用法,有没有办法计算每秒发送到的指令数CPU(每秒百万条指令 (MIPS))?是否可以找到指令集的类型(添加、比较、输入、跳转等)?
如有任何脚本或工具推荐(任何语言),我们将不胜感激。
perf stat --all-user ./my_program
将使用 CPU 性能计数器来记录它 运行 有多少用户-space 指令,以及有多少核心时钟周期花了。以及它使用了多少 CPU 时间,并将为您计算每个核心时钟周期的平均指令数,例如
3,496,129,612 instructions:u # 2.61 insn per cycle
它为你计算IPC;这通常比每 秒 的指令更有趣。 uops
每个时钟通常更有趣,但就您离最大化前端的接近程度而言。 您可以根据 instructions
和 task-clock
手动计算 MIPS。 对于大多数其他事件,perf 以每秒速率打印注释。
(如果你不使用 --all-user
,你可以使用 perf stat -e task-clock:u,instructions:u
,...让这些特定事件仅在 user-space 中计数,而其他事件可以总是计数,包括内部中断处理程序和系统调用。)
但如果您确实想要跨内核的总 MIPS 或平均 MIPS,以及是否计算睡眠,请参阅 instructions / task-clock
与 instructions / elapsed_time
的更多详细信息。
有关在静态可执行文件中的微型基准测试循环中使用它的示例输出,请参阅
How can I get real-time information at run-time
你的意思是从程序内部,只分析它的一部分吗?有一个 perf API,你可以在其中执行 perf_event_open
或其他操作。或者使用不同的库直接访问硬件性能计数器。
perf stat
非常适合对已隔离到独立程序中的循环进行微基准测试,该程序只是 运行 热循环一秒钟左右。
或者您可能有其他意思。 perf stat -I 1000 ... ./a.out
将每 1000 毫秒(1 秒)打印一次计数器值,以查看程序行为如何实时变化 以及您想要的任何时间 window(低至 10 毫秒)间隔)。
sudo perf top
是系统范围的,有点像 Unix top
还有 perf record --timestamp
记录每个事件样本的时间戳。 perf report -D
可能与此一起有用。看到http://www.brendangregg.com/perf.html,他提到了一些关于-T
(--timestamp
)的事情。我还没有真正使用过这个;我主要隔离单个循环 我正在调整为静态可执行文件 我可以 运行 在 perf stat
.
And is it possible to find the type of instruction set (add, compare, in, jump, etc)?
Intel x86 CPUs 至少有一个 b运行ch 指令的计数器,但其他类型没有区别,除了 FP 指令。这对于大多数具有性能计数器的架构来说可能很常见。
对于英特尔 CPUs,有 ocperf.py,perf
的包装器,带有更多微体系结构事件的符号名称。 (更新:plain perf
现在知道大多数 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
它不是为了告诉你什么指令是运行宁,你已经可以从跟踪执行中知道。大多数指令都是完全流水线的,所以有趣的是哪些端口的压力最大。例外是 divide/sqrt 单元:arith.divider_active
有一个计数器:“除法单元忙于执行除法或平方根运算时的循环数。考虑整数和浮点运算”。分频器没有完全流水线化,所以即使没有旧的 uops 准备好在端口 0 上执行,新的 divps
或 sqrtps
也不能总是启动。 (http://agner.org/optimize/)
相关:linux perf: how to interpret and find hotspots 使用 perf
识别热点。特别是使用自上而下的分析,您可以 perf
对调用堆栈进行采样,以查看哪些函数进行了大量昂贵的子调用。 (我提到这个是为了防止你真正想知道,而不是指令组合。)
相关:
- How do I determine the number of x86 machine instructions executed in a C program?
对于精确的动态指令计数,如果您使用的是 x86,则可以使用像 Intel PIN 这样的检测工具。 https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool.
perf stat
对 instructions:u
硬件的计数甚至应该或多或少是准确的,并且实际上在执行相同工作的同一程序的 运行 之间非常可重复。
在最近的 Intel CPUs 上,硬件支持记录条件/间接 b运行ches 的路径,因此您可以准确地重建哪些指令 运行 的顺序,假设没有自修改代码,并且您仍然可以读取任何 JIT 缓冲区。 Intel PT.
抱歉,我不知道 AMD CPUs 上的等效项是什么。