2013-12-26 1 views
2

Я использую gprof для анализа программы, работающей на Linux, которая использует интервал времени 25 мс (созданный timer_create()) для обновления глобальной переменной. Обработчик сигнала что-то вроде update_every_25ms(), он вызывает profile_dummy(), чтобы увеличить grobal переменную:gprof показывает простой обработчик сигнала занимает много CPU

static void update_every_25ms(int sig_nr) { profile_dummy(); } 
void profile_dummy(void) { global_var++; } 

Таймер создается через:

timer_t timer; 
struct itimerspec itimer; 
timer_create(CLOCK_MONOTONIC, NULL, &timer) 
itimer.it_interval.tv_sec = 0; 
itimer.it_interval.tv_nsec = 25 * 1000 * 1000; 
timer_settime(timer, 0, &itimer, NULL); 

Моя программа делать много тяжелых работ, но gprof показывает, что функции update_every_25ms() занимают большую часть времени, когда использование ЦП составляет 100%, а сама эта функция занимает около 1,53 мс за звонок!

Ниже приведены несколько групп выхода дргоЕ, когда интервал 25 мс:

%time cumulative self  calls self total name 
     seconds  seconds   ms/call ms/call 
3.72 116.26  7.76  22963 0.34 0.34  profile_dummy 

Здесь использование процессора составляет 60%. Зачем нужен профиль_dummy() 0,34 мс за звонок?

%time cumulative self  calls self total name 
     seconds  seconds   ms/call ms/call 
9.38 38.87  38.87 25349 0.00 0.00  profile_dummy 

Здесь использование ЦП составляет 100%. 38.87s/25349 = 1.53ms, но gprof выходы 0.00, что случилось?

%time cumulative self  calls self total name 
     seconds  seconds   ms/call ms/call 
6.21 270.58  57.72 59105  0.00 0.00  profile_dummy 

Здесь использование ЦП составляет 90%. И 57.72s/59105 = 0.98ms, но gprof выходы 0.00 тоже.

Это один выход дргоЕ, когда я изменил интервал таймера на 25s:

%time cumulative self  calls self total name 
     seconds  seconds   ms/call ms/call 
0.01 287.52  0.03 23  1.30 1.30  profile_dummy 

Функция просто увеличивает глобальную переменную, почему это нужно 1.30ms?

Спасибо за любой ответ.

+0

Возможно, отредактируйте вопрос, чтобы показать вызов timer_create() с параметрами, которые вы использовали –

+0

Спасибо jwpat7. Я добавил код таймера. – Dustin

+0

Есть ли какая-то особая причина, по которой вы не процитировали масштабирование ('us',' ms' и т. Д.), Напечатанное gprof как часть заголовков столбцов? – alk

ответ

0

Я просто рискую предположить здесь.

gprof имеет прерывание сигнала каждые 10 мс, в это время он отсчитывает счетчик программ (ПК). Общее время самообслуживания - это количество образцов, приземляющихся в этой рутине. Поскольку он также подсчитывает вызовы подпрограммы, он может получить среднее время автономной работы за звонок.

Обычно, когда ваша программа заблокирована, как и для ввода/вывода, спящего режима или многозадачности, ПК не имеет смысла, поэтому прерывания приостанавливаются. Вот почему gprof не может видеть I/O вообще.

Однако, если у вас есть собственное прерывание таймера, это может только замаскировать прерывание профайлера, а не приостанавливать его, заставляя его отвечать после того, как прерывание по таймеру отклонено, что может привести к тому, что ПК будет использоваться в обработчике прерываний.

Но это только предположение.

Если это не чисто академический вопрос, есть лучшие профилировщики, чем gprof.

+0

Большое спасибо. Есть ли способ проверить, является ли это причиной, по которой вы сказали? Если я ничего не сделаю, я попробую другие профилировщики. – Dustin

+0

@Dustin: Есть намного лучшие профилировщики, чем 'gprof', например [* oprofile *] (http://oprofile.sourceforge.net/news/) и [* Zoom *] (http://www.rotateright.com /), но лично я не просто заинтересован в проведении измерений. Я хочу сделать код как можно быстрее, и для меня, [* лучший профайлер - это ** нет ** профилировщик. *] (Http://stackoverflow.com/a/378024/23771) –

Смежные вопросы