代码之家  ›  专栏  ›  技术社区  ›  Michel Gokan Khan

基准测试-如何计算发送到CPU的指令数以查找已使用的MIP

  •  3
  • Michel Gokan Khan  · 技术社区  · 7 年前

    假设我有一个软件,并想使用 black-box 方法我有一个3.0GHz的CPU,有2个插槽和4个内核。如您所知,为了找出每秒指令数(IPS),我们必须使用以下公式:

    IPS = sockets*(cores/sockets)*clock*(instructions/cycle)
    

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

    但现在,我有两个问题:无论我的机器上运行的是哪种软件及其cpu使用情况,是否有任何方法可以计算每秒发送到cpu的指令数(每秒数百万条指令(MIPS))?是否可以找到指令集的类型(添加、比较、输入、跳转等)?

    任何脚本或工具建议(任何语言)都将不胜感激。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Peter Cordes    5 年前

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

    3,496,129,612      instructions:u            #    2.61  insn per cycle
    

    它为您计算IPC;这通常比 第二 uops 不过,就您离最大化前端的距离而言,每个时钟通常更有趣。 您可以从手动计算MIPS instructions task-clock 对于大多数其他事件,perf以每秒的速率打印注释。

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

    但请参见 How to calculate MIPS using perf stat 有关的更多详细信息 instructions / task-clock vs。 instructions / elapsed_time 如果您确实想要整个核心的总MIPS或平均MIPS,并计算睡眠与否。


    有关在静态可执行文件中的微型基准循环上使用它的输出示例,请参阅 Can x86's MOV really be "free"? Why can't I reproduce this at all?

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

    你的意思是从项目内部,只分析其中的一部分?有一个perf API,您可以在其中执行以下操作 perf_event_open 或者别的什么。或者使用其他库直接访问HW perf计数器。

    perf stat 对于将已隔离到独立程序中的循环进行微基准标记非常有用,该程序只运行热循环一秒钟左右。

    或者你的意思是别的。 perf stat -I 1000 ... ./a.out 将每隔1000毫秒(1秒)打印计数器值,以查看程序行为如何实时变化 您可以选择任何时间窗口(间隔10ms)。

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

    还有 perf record --timestamp 记录每个事件样本的时间戳。 perf report -D 与此一起使用可能会很有用。看见 http://www.brendangregg.com/perf.html ,他提到 -T ( --timestamp ).我没有真正使用过这个;我主要是将正在调优的单个循环隔离到可以运行的静态可执行文件中 性能统计


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

    英特尔x86 CPU至少有一个分支指令计数器,但除FP指令外,其他类型没有区别。这可能是大多数具有perf计数器的体系结构所共有的。

    对于Intel CPU,有 ocperf.py ,的包装器 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

    它不是用来告诉您正在运行什么指令的,您已经可以通过跟踪执行来告诉您了 。大多数指令都是完全管道化的,所以有趣的是哪些端口的压力最大。除法/sqrt单位是个例外:有一个计数器 arith.divider_active :“ 当除法单元忙于执行除法或平方根运算时循环。整数和浮点运算的帐户 “。分隔器没有完全管道化,因此 divps sqrtps 即使没有旧的UOP准备在端口0上执行,也无法始终启动。( http://agner.org/optimize/ )

    相关: linux perf: how to interpret and find hotspots 用于使用 性能 确定热点。尤其是使用自顶向下的分析 性能 对调用堆栈进行采样,以查看哪些函数会进行大量昂贵的子调用。(我提到这一点,以防你 真正地 想知道,而不是指令混合。)

    相关:


    对于精确的动态指令计数,如果您使用的是x86,则可以使用Intel引脚之类的检测工具 https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool

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

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


    对不起,我不知道AMD CPU上的等价物是什么。

    推荐文章