2012-10-19 2 views
4

Я использовал linux perf для профайла моей программы, и я не могу понять результат.Что означает «Образцы» в перфомансе?

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

Приведенный выше пример означает, что 'удовольствие' имеет два образца и способствует 10,5% накладных расходов,

и 80% из них вызывается из ABC, 20% от DEF. Я прав?

Теперь у нас есть только два образца, тогда как «perf» вычисляет долю ABC и DEF?

Почему они не 50%? доза 'perf' использует дополнительную информацию?

+1

Не могли бы вы предоставить синтаксис/опции, которые вы использовали для выполнения перфорации? – csj

ответ

0

Приведенный выше пример означает, что «удовольствие» имеет два образца и способствует 10,5% накладных расходов,

Да, эта часть perf report -g -n показывает, что 2 из 19 образцов (2 составляет 10,5% от 19) в самой функции foo. Еще 17 образцов были отобраны в другой функции.

Я только что воспроизвел ваш код с последним gcc (-static -O3 -fno-inline -fno-omit-frame-pointer -g) и perf (perf record -e cycles:u -c 500000 -g ./test12968422 для образцов с низким разрешением или -c 5000 для высокого разрешения). Теперь у перфоратора есть разные правила веса, но идея должна быть одинаковой. Если для программы есть только 2 образца, и оба находятся в foo, call-graph (perf report -n -g callee) составляет 50 для каждого из call_DEF/_ABC (без дополнительной информации). Эта программа на самом деле было 86% выполнения в обув, 61% из них при вызове из ABC, 25% из 86, когда вызывается из DEF:

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

Что вид дополнительной информации перфорация может использовать для восстановления дополнительной информации ? Я думаю, что это может быть собственный вес call_DEF и call_ABC; или это может быть частота «call_ABC-> foo» и «call_DEF-> foo» частей callchain во всех тестовых стеках вызовов.

С первыми версиями ядра Linux версии 4.4/4.10 Я не могу воспроизвести вашу ситуацию. Я добавил разное количество самостоятельной работы в call_ABC и call_DEF. Оба они просто называет foo для фиксированного объема работы. Теперь у меня есть 19 образцов -e cycles:u -c 54000 -g, 13 для call_ABC, 2 для call_DEF, 2 для удовольствия (и 2 в некоторых случайных функциях):

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 Linux ядра ,

Первого источник fun только работы, неадекватные акции, когда вызывается из ABC и от DEF:

#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; 
} 

Второго источник неравны работ в ABC и DEF с одинаковой небольшой работой в конкурсе:

#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; 
}