2

Моя цель - профилировать время выполнения каждой функции в модуле ядра. Используя образцы сценариев, которые я видел в Интернете, я придумал следующий сценарий, чтобы удовлетворить мои потребности. Но иногда я получаю отрицательные значения для рассчитанных латентностей. Хотя, они случаются редко, но я предполагаю, что это указывает на то, что с моим скриптом что-то не так. Может ли кто-нибудь помочь мне с этим, пожалуйста?Скрипт SystemTap для фильтрации задержек функций

probe module(@1).function(@2).call { 
    begin = gettimeofday_ns() 
} 

probe module(@1).function(@2).return { 
    if (begin>0) 
    stats <<< gettimeofday_ns() - begin 
} 

probe end { 
    if (begin == 0) { 
     printf("No samples observed so far.\n"); 

    } else { 
     printf("Distribution of %s latencies (in nanoseconds) for %d samples\n", @2, @count(stats)) 
     printf("max/avg/min: %d/%d/%d\n", @max(stats), @avg(stats), @min(stats)) 
     print(@hist_log(stats)) 
    } 
} 


global begin, stats 

ответ

1

Функции gettimeofday_*() могут приближаться только к времени разгона. Возможно, что через процессоры или через момент настройки времени значения не будут монотонно двигаться так, как вы ожидаете. get_cycles() является более монотонным на заданном процессоре, а также доступны несколько других функций, связанных с синхронизацией.

Кроме того, переменная begin является простым скаляром. Что делать, если одна и та же функция вызывается из нескольких потоков/cpus или возникает рекурсия? Он будет перезаписан. Этого должно быть достаточно (и работать правильно, с точки зрения вложения/параллелизма):

// no probe FOO.call 
probe module(@1).function(@2).return { 
    stats <<< gettimeofday_ns() - @entry(gettimeofday_ns()) 
} 
+1

Спасибо, это сработало! Я подозревал, что проблема заключается в том, что переменная «begin» является скалярной, но поскольку это мой опыт работы с SystemTap, не имел понятия, что делать. В любом случае, просто из любопытства: если бы я хотел сохранить проблему FOO.call и использовать начальную переменную, как раньше (в основном, не используя @entry), как я могу решить проблему с скалярной переменной? – soofyaan

+1

Вы можете сделать массив и проиндексировать его с помощью tid(). (Могут возникнуть другие осложнения, такие как рекурсивная функция, и в этом случае вам нужно индексировать также уровень вложенности, или ядро ​​может по какой-то причине пропустить зонд .call или .return, и в этом случае сценарий должен терпеть плохое состояние.) – fche

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