“perf stat”结果中有什么是停滞周期前端和停止周期后端?

有没有人知道perf stat结果中的“ 停顿 – 循环 – 前端”和“ 停滞 – 循环 – 后端”的含义? 我在网上search,但没有find答案。 谢谢

$ sudo perf stat ls Performance counter stats for 'ls': 0.602144 task-clock # 0.762 CPUs utilized 0 context-switches # 0.000 K/sec 0 CPU-migrations # 0.000 K/sec 236 page-faults # 0.392 M/sec 768956 cycles # 1.277 GHz 962999 stalled-cycles-frontend # 125.23% frontend cycles idle 634360 stalled-cycles-backend # 82.50% backend cycles idle 890060 instructions # 1.16 insns per cycle # 1.08 stalled cycles per insn 179378 branches # 297.899 M/sec 9362 branch-misses # 5.22% of all branches [48.33%] 0.000790562 seconds time elapsed 

要将由perf导出的通用事件转换为您可以运行的CPU文档原始事件:

 more /sys/bus/event_source/devices/cpu/events/stalled-cycles-frontend 

它会告诉你类似的东西

 event=0x0e,umask=0x01,inv,cmask=0x01 

根据英特尔文档SDM卷3B (我有一个核心i5-2520):

UOPS_ISSUED.ANY:

  • 每个周期增加RAT向RS发出的Uops数量。
  • 设置Cmask = 1,Inv = 1,Any = 1来计算该内核的停顿周期。

对于转换为事件= 0xb1的stalled-cycles-backend事件,umask = 0x01在我的系统上,相同的文档说:

UOPS_DISPATCHED.THREAD:

  • 统计每个周期每个线程将要发送的总共uops数
  • 设置Cmask = 1,INV = 1来计算失速周期。

通常情况下,停顿的周期是处理器在等待某些事情的周期(例如,在执行加载操作之后要对内存进行馈送),并且没有任何其他的事情要做。 此外,CPU的前端部分是负责取指令并将其译码的硬件(将其转换成UOP),后端部分负责有效地执行UOP。

理论:

我们从这里开始:现在的CPU是超标量的,这意味着它们可以在每个周期(IPC)执行多个指令。 最新的英特尔架构可以达到4个IPC(4个x86指令解码器)。 让我们不要把macros观/微观融合到讨论中,让事情更复杂:)。

通常情况下,由于各种资源争夺,工作负载不会达到IPC = 4。 这意味着CPU正在浪费周期 (指令的数量由软件给出,CPU必须在尽可能less的周期内执行)。

我们可以将CPU花费的总周期分为三类:

  1. 指令退休的周期(有用的工作)
  2. 在后端花费的周期(浪费)
  3. 在前端花费的周期(浪费)。

要获得4的IPC, 退休周期的数量必须接近总周期数。 请记住,在这个阶段,所有的微操作(uOps)退出pipe道,并将其结果写入寄存器/caching。 在这个阶段,甚至可以有4个以上的uOps退休,因为这个数字是由执行端口的数量给出的。 如果你只有25%的周期退休4万欧,那么你将有一个1的整体IPC。

由于CPU必须等待资源(通常是内存)或完成长时间延迟指令(例如,收发器 – sqrt,倒数,除法等),所以在后端停滞周期是浪费。

在前端停顿周期是浪费的,因为这意味着前端不向后端馈送微操作。 这可能意味着您在指令高速caching中未命中,或者在微操作高速caching中尚未解码的复杂指令。 即时编译代码通常expression这种行为。

另一个失速原因是分支预测失误。 这就是所谓的糟糕的猜测。 在这种情况下,uOps被发布,但由于BP预测错误,所以被丢弃。

configuration器中的实现:

你如何解释BE和FE停滞周期?

不同的configuration文件在这些指标上有不同的方法。 在vTune中,类别1到3合计为100%的周期。 这是合理的,因为无论你有你的CPU停滞(没有uOps退休),要么执行有用的工作(uOps)退休。 在此处查看更多信息: https : //software.intel.com/sites/products/documentation/doclib/stdxe/2013SP1/amplifierxe/snb/index.htm

在perf这通常不会发生。 这是一个问题,因为当你看到125%的周期停滞在前端 ,你不知道如何真正解释这一点。 你可以将大于1的度量值与有4个解码器的事实联系起来,但如果继续推理,那么IPC将不匹配。

更好的是,你不知道问题有多大。 125%是什么? #cycles是什么意思呢?

我个人看起来有点怀疑perf的BE和FE停滞周期,并希望这将得到修复。

也许我们会通过debugging这里的代码来得到最终的答案: http : //git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/tools/perf/builtin-stat.c

当一个CPU周期在其中不进行时,CPU周期“停滞”。

处理器stream水线由多个阶段组成:前端是一组这样的阶段,它们负责提取和解码阶段,而后端执行指令。 前端和后端之间有一个缓冲区,所以当前者停滞时,后者仍然有一些工作要做。

取自http://paolobernardi.wordpress.com/2012/08/07/playing-around-with-perf/

根据这些事件的作者,他们定义松散,并由可用的CPU性能计数器近似。 据我所知,perf不支持基于几个硬件事件计算某个合成事件的公式,所以它不能使用Intel优化手册(在VTune中实现)中的前端/后端停顿绑定方法。 http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf“B.3.2分层自顶向下的性能表征方法”;

 %FE_Bound = 100 * (IDQ_UOPS_NOT_DELIVERED.CORE / N ); %Bad_Speculation = 100 * ( (UOPS_ISSUED.ANY – UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES ) / N) ; %Retiring = 100 * ( UOPS_RETIRED.RETIRE_SLOTS/ N) ; %BE_Bound = 100 * (1 – (FE_Bound + Retiring + Bad_Speculation) ) ; N = 4*CPU_CLK_UNHALTED.THREAD" (for SandyBridge) 

正确的公式可以与一些外部脚本一起使用,就像在Andi Kleen的toplev.py -tools( toplev.py )中完成的一样: https : //github.com/andikleen/pmu-tools (source), http : toplev.py / blog / p / 262 (description):

 % toplev.py -d -l2 numademo 100M stream ... perf stat --log-fd 4 -x, -e {r3079,r19c,r10401c3,r100030d,rc5,r10e,cycles,r400019c,r2c2,instructions} {r15e,r60006a3,r30001b1,r40004a3,r8a2,r10001b1,cycles} numademo 100M stream ... BE Backend Bound: 72.03% This category reflects slots where no uops are being delivered due to a lack of required resources for accepting more uops in the Backend of the pipeline. ..... FE Frontend Bound: 54.07% This category reflects slots where the Frontend of the processor undersupplies its Backend. 

承诺引入了停滞周期前端和停滞周期后端事件,而不是原始的通用stalled-cycles

http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?id=8f62242246351b5a4bc0c1f00c0c7003edea128a

 author Ingo Molnar <mingo@el...> 2011-04-29 11:19:47 (GMT) committer Ingo Molnar <mingo@el...> 2011-04-29 12:23:58 (GMT) commit 8f62242246351b5a4bc0c1f00c0c7003edea128a (patch) tree 9021c99956e0f9dc64655aaa4309c0f0fdb055c9 parent ede70290046043b2638204cab55e26ea1d0c6cd9 (diff) 

perf事件:添加通用前端和后端停顿循环事件定义添加两个通用硬件事件:前端和后端停滞周期。

这些事件测量CPU正在执行代码但是其function没有被充分利用的条件。 理解这些情况并分析它们是代码优化工作stream程的一个重要的子任务。

这两个事件都限制了性能:大多数前端分区往往是由分支错误预测或取指cachemisses引起的,后端分摊可能是由各种资源短缺或低效的指令调度造成的。

前端是最重要的,如果指令stream不能保持,代码不能快速运行。

一个过度使用的后端可能会导致前端摊位,因此也必须密切关注。

确切的组成是非常程序逻辑和指令组合依赖。

我们使用“stall”,“front-end”和“back-end”这两个术语,尝试从特定的CPU中使用最接近这些概念的可用事件。

抄送:Peter Zijlstra抄送:Arnaldo Carvalho de Melo抄送:Frederic Weisbecker链接: http ://lkml.kernel.org/n/tip-7y40wib8n000io7hjpn1dsrm@git.kernel.org签名:Ingo Molnar

  /* Install the stalled-cycles event: UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */ - intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES] = 0x1803fb1; + intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1; - PERF_COUNT_HW_STALLED_CYCLES = 7, + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7, + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,