Приведенный выше пример означает, что «удовольствие» имеет два образца и способствует 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;
}
Не могли бы вы предоставить синтаксис/опции, которые вы использовали для выполнения перфорации? – csj