2012-10-19 5 views
4

나는 내 프로그램을 프로파일 링하기 위해 리눅스 퍼포먼스를 사용했기 때문에 결과를 이해할 수 없다. perf 출력에서 ​​'샘플'은 무엇을 의미합니까?

 
10.5% 2  fun  .......... 
     | 
     |- 80% - ABC 
     |  call_ABC 
     -- 20% - DEF 
       call_DEF 

위의 예는 '즐거운'개의 샘플을 갖는 것을 의미하며 10.5 %의 오버 헤드, DEF에서

그들 중 80 %는 ABC에서 호출하고, 20 %를 기여한다. 내가 맞습니까?

이제 우리는 두 개의 샘플 만 가지고 있습니다. 그러면 'perf'가 ABC와 DEF의 분수를 어떻게 계산합니까?

왜 50 %가 아닌가요? 복용량 'perf'는 추가 정보를 사용합니까?

+1

perf를 실행하는 데 사용한 구문/옵션을 제공해 주시겠습니까? – csj

답변

0

상기 예

예, perf report -g -n이 2 부 (19)의 샘플 (2 (19)의 10.5 % 임) 것을 나타내고, '재미'개의 샘플을 갖는 것을 의미하고, 10.5 %의 오버 헤드 기여 foo 함수 자체에서. 17 개의 다른 샘플이 다른 기능에서 샘플링되었습니다.

최근 gcc (-static -O3 -fno-inline -fno-omit-frame-pointer -g) 및 perf (저해상도 샘플의 경우 perf record -e cycles:u -c 500000 -g ./test12968422 또는 고해상도의 경우 -c 5000)로 코드를 재현했습니다. 이제 perf에는 약간 다른 가중치 규칙이 있지만 아이디어는 동일해야합니다. 프로그램에 대해 2 개의 샘플 만 있고 모두 foo에있는 경우 call_Dep/_ABC (추가 정보 없음)마다 호출 그래프 (perf report -n -g callee)는 50입니다. (86)의 25 % DEF에서 호출 할 때, ABC에서 호출 할 때이 프로그램은 실제로 foo는에서 런타임의 86 %, 그 중 61 %를 가지고 :

100% 2 fun 
- fun 
    + 50% call_DEF 
    + 50% call_ABC 

추가 정보 반환 한 종류 더 자세한 정보를 재구성하는 데 사용할 수있는 무엇 ? call_DEF와 call_ABC의 자체 가중치 일 수 있다고 생각합니다. 또는 모든 샘플 호출 스택에서 callchain의 "call_ABC-> foo"및 "call_DEF-> foo"부분의 빈도 일 수 있습니다.

Linux 커널 버전 4.4/4.10의 perf에서는 상황을 재현 할 수 없습니다. 나는 call_ABC와 call_DEF에서 각각 다른 양의 작업을 추가했다. 둘 다 고정 된 작업량에 대해서 foo를 호출합니다.

Children Self Samples Symbol 
     74% 68%  13 [.] call_ABC 
     16% 10.5%  2 [.] call_DEF 
    10.5% 10.5%  2 [.] fun 
    - fun 
     + 5.26% call_ABC 
     + 5.26% call_DEF 

그래서,하지 3.2 리눅스 커널의 시대에서 반환 한의 최신 버전을보십시오 : 지금은 19 개 -e cycles:u -c 54000 -g의 샘플 call_ABC 13, (어떤 임의의 기능과 2) 재미 call_DEF, 2 2이 .

fun에만 작업

먼저 소스, DEF ABC로부터 호출 inequal 주 : 재미 동일 작은 일에 ABC와 DEF에 inequal 작업

#define g 100000 
int a[2+g]; 

void fill_a(){ 
    a[0]=0; 
    for(int f=0;f<g;f++) 
     a[f+1]=f; 
} 

int fun(int b) 
{ 
    while(a[b]) 
     b=a[b]; 
    return b; 
} 

int call_ABC(int b) 
{ 
    int d = b; 
    b = fun(d); 
    return d-b; 
} 

int call_DEF(int b) 
{ 
    int e = b; 
    b = fun(e); 
    return e+b; 
} 

int main() 
{ 
    int c,d; 
    fill_a(); 
    c=call_ABC(100000); 
    c=call_DEF(45000); 
    return c+d; 
} 

두 번째 소스 :

#define g 100000 
int a[2+g]; 

void fill_a(){ 
    a[0]=0; 
    for(int f=0;f<g;f++) 
     a[f+1]=f; 
} 

int fun(int b) 
{ 
    while(a[b]) 
     b=a[b]; 
    return b; 
} 

int call_ABC(int b) 
{ 
    int d = b; 
    while(a[d]) 
     d=a[d]; 
    b = fun(5000); 
    return d-b; 
} 

int call_DEF(int b) 
{ 
    int e = b; 
    while(a[e]) 
     e=a[e]; 
    b = fun(5000); 
    return e+b; 
} 

int main() 
{ 
    int c,d; 
    fill_a(); 
    c=call_ABC(100000); 
    c=call_DEF(20000); 
    return c+d; 
} 
관련 문제