“性能统计”结果中的停滞周期前端和停滞周期后端是什么?


81

有人知道perf stat结果中的stalled -cycles-frontendstalled-cycles-backend是什么意思吗?我在互联网上搜索,但没有找到答案。谢谢

$ 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

我不确定真正的问题在这里。问的是CPU的前端和后端是什么?请阅读此高级介绍。这回答了你的问题了吗?
阿里

我搜索和搜索类似的答案......这是最有用的资源,我从英特尔发现:software.intel.com/en-us/articles/...
Jmoney38

不,几乎没有人知道这些的真正含义。但引用这个职位(我不完全理解尚)联合手册(如哥斯达黎加热带雨林的答案),是我发现的最接近:sites.utexas.edu/jdm4372/2014/06/04/...
jberryman

Answers:


58

理论:

让我们从这一点开始:当今的CPU是超标量的,这意味着它们每个周期(IPC)可以执行多个指令。最新的英特尔架构最多可支持4个IPC(4个x86指令解码器)。让我们不要将宏/微融合引入讨论,以使事情更加复杂:)。

通常,由于各种资源争用,工作负载不会达到IPC = 4。这意味着CPU浪费了周期(指令数量由软件提供,CPU必须在尽可能短的周期内执行它们)。

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

  1. 指令被淘汰的周期(有用的工作)
  2. 在后端花费的周期(已浪费)
  3. 在前端花费的周期(已浪费)。

要使IPC为4,退休周期数必须接近周期的总数。请记住,在此阶段,所有微操作(uOps)都将从管道中退出,并将其结果提交到寄存器/缓存中。在此阶段,您将有4个以上的uOps退出,因为此数目由执行端口的数目给定。如果您只有25%的周期要退出4 uOps,那么总体IPC将为1。

由于CPU必须等待资源(通常是内存)或完成长等待时间的指令(例如,先验-sqrt,倒数,除法等),后端停滞循环是一种浪费。

停滞在前端循环是一种浪费,因为这意味着前端不会通过微操作为后端提供数据。这可能意味着您在指令缓存中有未命中,或者在微操作缓存中尚未解码的复杂指令。即时编译的代码通常表示这种行为。

另一个停顿原因是分支预测未命中。这就是所谓的不良猜测。在这种情况下,会发出uOps,但由于BP预测错误而将其丢弃。

分析器中的实现:

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

不同的探查器在这些指标上有不同的方法。在vTune中,类别1至3相加得出100%的周期。这样做合理,因为要么您的CPU停止运行(没有uOps退出),要么它执行了有用的工作(uOps)退出。在此处查看更多信息:https : //software.intel.com/sites/products/documentation/doclib/stdxe/2013SP1/amplifierxe/snb/index.htm

在性能方面,这通常不会发生。这是一个问题,因为当您看到前端停滞了125%的周期时,您不知道该如何真正地解释它。您可以将> 1指标与4个解码器的事实联系起来,但是如果继续推理,则IPC将不匹配。

更好的是,您不知道问题有多严重。什么占125%?那么#cycles是什么意思?

我个人对perf的BE和FE停滞周期有些怀疑,希望这一问题能够解决。

我们可能会通过从以下位置调试代码来获得最终答案:http : //git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/tools/perf/builtin-stat.c


VTune中将哪些事件用作FE和BE?曼努埃尔(Manuel)在桑迪桥(Sandy Bridge)上发布了perf的事件。有时,解码器无法解码4条指令(realworldtech.com/sandy-bridge/4-有3种简单的解码器无法解码复杂的命令)。
osgx

的确有一个复杂的解码器,但它也可能能够解码简单的指令。我用指向vTune计数器的链接更新了我的帖子。它使用与perf相同的计数器,但我认为vTune的组合方式有所不同。
VAndrei 2015年

4
Vtune使用software.intel.com/zh-cn/articles/…将“ IDQ_UOPS_NOT_DELIVERED.CORE / SLOTS”用作“前端绑定”,将“ 1-(前端绑定+退休+错误的推测)”用作“后端绑定”,其中“退休= UOPS_RETIRED.RETIRE_SLOTS / SLOTS”,“错误推测=(UOPS_ISSUED.ANY – UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES)/ SLOTS”和“ SLOTS = 4 * CPU_CLK_UNHALTED.THREAD”等于流水线”。
osgx

1
对于Sandy Bridge,英特尔的优化手册intel.com/content/dam/www/public/us/en/documents/manuals/…在“ 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);%退休= 100 *(UOPS_SIREDIRED.RET *(1 –(FE_Bound +退休+错误的推测)); N = 4 * CPU_CLK_UNHALTED.THREAD“
osgx

@osgx谢谢。现在我们知道这些指标在vTune中意味着什么,它们加起来达到100%。下一个问题是,为什么perf计算它们的方式有所不同?它是错误还是在其背后有含义?
VAndrei 2015年

42

要将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发出的Uop数量。
  • 设置Cmask = 1,Inv = 1,Any = 1,以计算该内核的停顿周期。

对于在我的系统上转换为event = 0xb1,umask = 0x01的停滞循环后端事件,同一文档说:

UOPS_DISPATCHED.THREAD:

  • 计算每个周期每个线程要分配的微指令总数
  • 设置Cmask = 1,INV = 1来计算失速周期。

通常,停顿周期是指处理器在等待某些东西(例如,执行加载操作后要馈入内存)并且没有其他任何事情要做的周期。此外,CPU的前端部分是负责获取和解码指令(将它们转换为UOP)的硬件,而后端部分则负责有效地执行UOP。


感谢您的回复。那么停转和空闲之间有什么区别?
大帆2014年

2
停转和闲置是相同的。CPU处于空闲状态,因为其由于指令流水线不移动而停滞。
Milind Dumbare 2014年

@Milind,应该不应该有什么区别,停滞应该是“我们不能进步,因为下一阶段不允许这样做”,而闲置应该是“没有什么要处理的”?
Surt 2014年


11

这些事件的作者认为,它们的定义很松散,并且可用可用的CPU性能计数器来近似。据我所知,perf不支持基于几个硬件事件来计算某些合成事件的公式,因此它不能使用英特尔优化手册(在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的pmu-tools(toplev.py)中所做的那样:https : //github.com/andikleen/pmu-tools(源),http://halobates.de/blog/ p / 262(描述):

% 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.

提交了引入停滞循环前端和停滞循环后端事件的Commit,而不是原始的Universal 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执行代码时的条件,但其功能未得到充分利用。了解这种情况并进行分析是代码优化工作流的重要子任务。

这两个事件都会限制性能:大多数前端停顿往往是由分支预测错误或指令获取缓存丢失引起的,后端停顿可能是由于各种资源短缺或指令调度效率低下引起的。

前端停顿是更重要的停顿:如果不保持指令流,代码将无法快速运行。

后端的过度使用可能导致前端停滞,因此也必须引起注意。

确切的构成取决于程序逻辑和指令混合。

我们宽松地使用术语“停顿”,“前端”和“后端”,并尝试使用来自近似这些概念的特定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,

到底这是perf错误吗?因为FE + BE +?不要增加已知的理论值,很难评估您的代码问题有多大。当您看到75%的FE停转时,需要将其与某些东西进行比较。在100%中说75%的代码停滞在FE或BE中具有完全不同的含义和价值。从我所看到的,甚至toplev.py都有相同的问题。如果这不是问题,我们如何解释指标?是什么使指标高或低?
VAndrei 2015年

VAndrei,您有SandyBridge(+ -1代)的简短且可复制的示例吗?对于perf statFE> 100%还是对于toplev.py?我只是从简短的简单循环开始,就有了3G指令的3G周期(1G是具有0.00%丢失率的分支),其中包含2G FE停顿(perf stat)和1G BE停顿(IPC = 1.00)。我认为问题在于为复杂的OOO磁芯正确定义“失速”,另一个是正确解释toplev.py结果。
osgx

我在此处发布的代码:stackoverflow.com/questions/28961405/…应该是前端绑定。其中有很多分支未命中,因此会产生FE停顿。关于绑定,您需要等待RAM数据的工作负载。在缓冲区中分配物理内存大小的1/2,然后使用LCG(类似于我的代码)在缓冲区中的随机位置执行读/修改/写操作。除了RMW事务外,这还会生成少量指令,并且内核将在RAM中停滞在BE中等待。
VAndrei 2015年

生成有限元绑定的工作负载是一个很大的挑战。请尝试使用分支微基准测试,但如果没有,则需要更复杂的工具。FE停顿将由大量指令高速缓存未命中产生。为了做到这一点,您需要一个很大的代码,并且要跳过很长的代码才能导致多个I $未命中。在这一点上,我还没有关于如何在微基准测试中进行有限元约束工作负载的想法。
VAndrei 2015年

我认为您会对以下链接感兴趣:stackoverflow.com/questions/1756825/…您可以使用其中一些讨论的技术来刷新I $,从而生成FE停顿。
VAndrei 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.