'perf stat'결과에서 stalled-cycles-frontend 및 stalled-cycles-backend는 무엇입니까?


83

누구든지 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의 프런트 엔드와 백엔드가 무엇인지 묻고 있습니까? 이 매우 높은 수준의 소개를 읽으십시오 . 이것이 귀하의 질문에 대답합니까?
알리

유사한 답변을 검색하고 검색했습니다 ... 이것은 Intel에서 찾은 가장 유용한 리소스였습니다. software.intel.com/en-us/articles/…
Jmoney38

아니, 그게 진짜 의미하는 바는 거의 아무도 모른다. 그러나이 게시물 (아직 완전히 이해하지 못함)과 결합 된 매뉴얼 (Manuel Selva의 답변에서와 같이)을 참조하는 것이 내가 찾은 가장 가까운 것입니다. sites.utexas.edu/jdm4372/2014/06/04/…
jberryman

답변:


60

이론 :

이제부터 시작해 보겠습니다. 오늘날의 CPU는 수퍼 스칼라이므로주기 당 하나 이상의 명령 (IPC)을 실행할 수 있습니다. 최신 Intel 아키텍처는 최대 4 개의 IPC (4 개의 x86 명령어 디코더)까지 확장 할 수 있습니다. 더 복잡하게 만들기 위해 매크로 / 마이크로 융합을 논의하지 마십시오. :).

일반적으로 워크로드는 다양한 리소스 경합으로 인해 IPC = 4에 도달하지 않습니다. 이것은 CPU가주기를 낭비하고 있음을 의미합니다 (명령의 수는 소프트웨어에 의해 제공되며 CPU는 가능한 한 적은 주기로 실행해야합니다).

CPU가 소비하는 총주기를 세 가지 범주로 나눌 수 있습니다.

  1. 지침이 폐기되는주기 (유용한 작업)
  2. 백엔드에서 소비되는주기 (낭비 됨)
  3. 프런트 엔드에서 소비 된 사이클 (낭비 됨).

IPC 4를 얻으려면 폐기 되는 주기 수가 총 주기 수에 가까워 야합니다. 이 단계에서는 모든 마이크로 작업 (uOps)이 파이프 라인에서 폐기되고 그 결과를 레지스터 / 캐시에 커밋합니다. 이 단계에서는 4 개 이상의 uOps가 폐기 될 수 있습니다.이 숫자는 실행 포트 수로 지정되기 때문입니다. 4 uOps를 폐기하는주기의 25 % 만있는 경우 전체 IPC는 1입니다.

백 엔드에서 교착 상태주기 (- SQRT, 역수, 부서 등 예를 들어 transcedentals) CPU가 자원 (보통 메모리)를 기다려야 또는 긴 대기 시간 지침을 완료하기 때문에 낭비입니다.

프런트 엔드에서 교착 상태주기는 낭비 프런트 엔드 마이크로 작업으로 백 엔드를 공급하지 않는 것을 의미하기 때문이다. 이는 명령어 캐시에 누락이 있거나 아직 micro-op 캐시에서 디코딩되지 않은 복잡한 명령어가 있음을 의미 할 수 있습니다. Just-in-time 컴파일 된 코드는 일반적으로이 동작을 표현합니다.

또 다른 지연 이유는 분기 예측 미스입니다. 이를 나쁜 추측이라고합니다. 이 경우 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을 참조하십시오.

perf에서는 일반적으로 발생하지 않습니다. 125 % 사이클이 프런트 엔드에서 멈춘 것을 볼 때 실제로이를 해석하는 방법을 알지 못 하기 때문에 문제가됩니다 . 4 개의 디코더가 있다는 사실과> 1 메트릭을 연결할 수 있지만 추론을 계속하면 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 2015 년

복잡한 디코더도 있지만 간단한 명령을 디코딩 할 수도 있습니다. vTune 카운터 링크로 게시물을 업데이트했습니다. perf와 동일한 카운터를 사용하지만 vTune은 다르게 결합한다고 생각합니다.
VAndrei

4
Vtune은 software.intel.com/en-us/articles/… "IDQ_UOPS_NOT_DELIVERED.CORE / SLOTS"를 "프런트 엔드 바운드"로, "1-(프런트 엔드 바운드 + 은퇴 + 나쁜 추측)"을 "백엔드 바운드"로 사용합니다. 여기서 " Retiring = UOPS_RETIRED.RETIRE_SLOTS / SLOTS ","Bad Speculation = (UOPS_ISSUED.ANY – UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES) / SLOTS "및"SLOTS = 4 * 시스템 CPU_CLK_UNHALTED.THREAD "와 같음 ".
osgx 2015 년

1
Sandy Bridge의 경우 Intel의 최적화 매뉴얼 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); % Retiring = N = 100; % BE_SLOTS / N = 100 * (1 – (FE_Bound + Retiring + Bad_Speculation)); N = 4 * CPU_CLK_UNHALTED.THREAD "
osgx

@osgx 감사합니다. 이제 vTune에서 메트릭이 의미하는 바가 무엇이며 합산하면 100 %가됩니다. 다음 질문은 왜 perf가 그것들을 다르게 계산합니까? 버그입니까, 아니면 의미가 있습니까?
VAndrei

43

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로 변환되는 stalled-cycles-backend 이벤트의 경우 동일한 문서에 다음과 같이 표시됩니다.

UOPS_DISPATCHED.THREAD :

  • 각 사이클에서 스레드 당 디스패치 할 총 uop 수를 계산합니다.
  • 스톨 사이클을 계산하려면 Cmask = 1, INV = 1을 설정합니다.

일반적으로 지연된주기는 프로세서가 무언가를 기다리고 있고 (예를 들어로드 작업을 실행 한 후 메모리가 공급 될 때까지) 다른 작업이없는주기입니다. 또한 CPU의 프런트 엔드 부분은 백엔드 부분이 UOP를 효과적으로 실행하는 역할을하는 명령을 가져오고 디코딩 (UOP로 변환)하는 하드웨어 부분입니다.


답장을 보내 주셔서 감사합니다. 그래서 지체와 유휴의 차이점은 무엇입니까?
Dafan 2014 년

2
중단 및 유휴 상태는 동일합니다. CPU는 명령 파이프 라인이 움직이지 않아 정지 되었기 때문에 유휴 상태입니다.
Milind Dumbare 2014 년

@Milind, 차이가 있어야하지 않습니까? "다음 단계가이를 허용하지 않기 때문에 우리는 진행하지 않습니다.", 유휴 상태는 "처리 할 것이 없습니다"여야합니까?
Surt

13

파이프 라인이 진행되지 않으면 CPU주기가 "지연"됩니다.

프로세서 파이프 라인은 여러 단계로 구성됩니다. 프런트 엔드는 가져 오기 및 디코딩 단계를 담당하는 이러한 단계의 그룹이고 백 엔드는 명령을 실행합니다. 프런트 엔드와 백 엔드 사이에는 버퍼가 있으므로 전자가 멈춰도 후자는 여전히 할 일이 있습니다.

http://paolobernardi.wordpress.com/2012/08/07/playing-around-with-perf/ 에서 가져옴


2
어떻게 우리가 사이클보다 더 많은 실속을 가질 수 있습니까?
osgx

11

이러한 이벤트의 작성자에 따르면 이러한 이벤트는 느슨하게 정의되었으며 사용 가능한 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의 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.

원래 유니버설 대신 지연된 사이클 프런트 엔드 및 지연된 사이클 백엔드 이벤트를 도입 한 커밋 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)

성능 이벤트 : 일반 프런트 엔드 및 백엔드 지연주기 이벤트 정의 추가 두 가지 일반 하드웨어 이벤트 (프런트 엔드 및 백엔드 지연주기)를 추가합니다.

이러한 이벤트는 CPU가 코드를 실행하지만 해당 기능이 완전히 활용되지 않을 때 조건을 측정합니다. 이러한 상황을 이해하고 분석하는 것은 코드 최적화 워크 플로의 중요한 하위 작업입니다.

두 이벤트 모두 성능을 제한합니다. 대부분의 프런트 엔드 중단은 분기 오 예측 또는 명령 가져 오기 캐시 누락으로 인해 발생하는 경향이 있으며, 백엔드 중단은 다양한 리소스 부족 또는 비효율적 인 명령 스케줄링으로 인해 발생할 수 있습니다.

프런트 엔드 스톨이 더 중요한 요소입니다. 명령어 스트림이 유지되지 않으면 코드가 빠르게 실행될 수 없습니다.

백엔드를 과도하게 사용하면 프론트 엔드 중단이 발생할 수 있으므로주의를 기울여야합니다.

정확한 구성은 프로그램 로직과 명령어 믹스에 따라 다릅니다.

우리는 '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,

그래서 결국 그것은 성능의 오류입니까? FE + BE +? 알려진 이론적 가치에 추가하지 마십시오. 코드의 문제가 얼마나 큰지 평가하기가 어렵습니다. 어떤 것과 비교해야하는 75 %의 FE 정지를 볼 때. 100 % 중 75 %가 FE 또는 BE에서 코드가 멈춘다 고 말하면 완전히 다른 의미와 가치를 갖습니다. 내가 본 것에서 toplev.py조차도 같은 문제가 있습니다. 이것이 문제가되지 않는다면 메트릭을 어떻게 해석합니까? 메트릭을 높거나 낮게 만드는 것은 무엇입니까?
VAndrei

VAndrei, SandyBridge (+-1 세대)에 대한 짧고 재현 가능한 예제가 있습니까? 모두 perf statFE> 100 % 및 toplev.py 하시나요? 방금 간단한 간단한 루프에서 시작하여 2G FE 스톨 ( perf stat) 및 1G BE 스톨 (IPC = 1.00) 이있는 3G 명령 (1G는 0.00 % 미스율의 분기 임)에 대한 3G 사이클이 있습니다 . 문제는 복잡한 OOO 코어에 대해 "stall"을 올바르게 정의하는 것이고 다른 하나는 toplev.py결과 를 올바르게 해석하는 것 입니다.
osgx 2015 년

여기에 게시 한 코드 : stackoverflow.com/questions/28961405/… 는 프런트 엔드 바인딩되어야합니다. 많은 분기 누락이 있으므로 FE 중단이 발생합니다. BE 바인딩과 관련하여 RAM 데이터에서 대기하는 워크로드가 필요합니다. 실제 메모리 크기의 1/2을 버퍼에 할당하고 LCG (예 : 내 코드)를 사용하여 버퍼의 임의 위치에서 읽기 / 수정 / 쓰기 작업을 수행합니다. 이는 RMW 트랜잭션 외에 적은 수의 명령을 생성하고 코어는 RAM 데이터에서 대기하는 BE에서 멈 춥니 다.
VAndrei 2015 년

FE 바운드 워크로드를 생성하는 것은 상당히 어려운 일입니다. 분기 마이크로 벤치 마크가 작동하지만 더 복잡한 것이 필요하지 않은 경우 시도하십시오. FE 중단은 많은 수의 명령어 캐시 미스로 인해 생성됩니다. 그렇게하려면 여러 I $ 미스로 이어질 수 있도록 멀리 점프하는 큰 코드가 필요합니다. 이 시점에서는 마이크로 벤치 마크에서 FE 바운드 워크로드를 만드는 방법에 대한 아이디어가 없습니다.
VAndrei

이 링크에 관심이있을 것 같습니다 : stackoverflow.com/questions/1756825/… 논의 된 기술 중 일부를 사용하여 I $를 플러시하고 따라서 FE 중단을 생성 할 수 있습니다.
VAndrei
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.