March 20, 2012

perf : современный Linux профилировщик

Иногда возникает необходимость заглянуть внутрь программы, что-бы посмотреть почему она "так тормозит". Естественно начинается все с высокоуровневых средств htop/atop/nettop/iotop/sar. Но если они показывают, что производительность упирается в процессор, то необходимо знать какие функции требуют больше всего вычислительных мощностей. Это может помочь как переписать свою программу для провышения производительности, так и подобрать оптимальные настройки для чужой.

Собственно функция профилировщика - найти узкие места в программе и выдать нам как можно больше информации о том куда уходят процессорные такты. Можно выделить три основных модели профилирования:

Гарантированное профилирование (determine - не нашел как перевести это лучше). Целевая программа модифицируется (чаще всего перекомпилируется с определенными флагами - -pg для gcc). - в код внедряются вызовы библиотеки профилирования, собирающие информацию о выполняемой программе и передающие ее профилировщику. Наиболее часто замеряется время выполнения каждой функции и после тестового прогона программы можно увидеть вывод, подобный следующему:

 %   cumulative   self              self     total
time   seconds   seconds    calls  ms/call  ms/call  name
33.34      0.02     0.02     7208     0.00     0.00  open
16.67      0.03     0.01      244     0.04     0.12  offtime
16.67      0.04     0.01        8     1.25     1.25  memccpy
16.67      0.05     0.01        7     1.43     1.43  write

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