измерить время в функции в C - PullRequest
5 голосов
/ 14 сентября 2011

Я отлаживаю приложение C и хотел бы узнать, сколько времени оно тратит на выполнение определенной функции.

Я мог бы изменить исходный код и добавить еще немного кода для измерения, но мне это не кажется правильным. Я бы предпочел сделать это с внешним приложением, не перекомпилируя каждый раз.

Я обнаружил, что в GDB можно установить точку останова, поэтому я подумал, что можно отслеживать время с помощью аналогичного инструмента с помощью простой процедуры: - установить точку останова - при остановке измерьте фактическое время и запустите функцию - при выходе из функции снова измеряйте время Тем не менее, я не нашел способ сделать это в GDB: (

есть идеи? Спасибо

Ответы [ 5 ]

2 голосов
/ 08 марта 2016

У меня есть вспомогательная функция в моем ~ / .gdbinit:

define timeme
set $last=clock()
n
set $timing=clock() - $last
if $timing>$arg0
printf "***long***\n"
end
printf "%d cycles, %f seconds\n", $timing, (float)$timing / 1000000
end

Возможно, вам придется настроить 1000000 в зависимости от того, какая у вас реализация CLOCKS_PER_SEC на вашей платформе.

Использованиетривиально;запустите помощника, который выполнит следующий шаг и выдаст информацию о времени:

Breakpoint 2, install_new_payload_from_meta (snmp_meta=0x7eee81c0, pkt=0x0, entry=0x7d4f4e58) at /home/sgillibr/savvi-dc-snmp/recipies.c:187
(gdb) timeme 100000
***long***
580000 cycles, 0.580000 seconds
(gdb)

Очевидно, что разрешение может быть недостаточным для некоторых нужд, хотя оно оказывается очень полезным.

2 голосов
/ 14 сентября 2011

gprof только надежно - по моему опыту, работает только вообще - если вы статически связываете -pg скомпилированные версии каждой библиотеки, включая библиотеку C. Вы можете попробовать сделать это, используя опцию -profile gcc (которая делает то, что делает -pg плюс пытается добавить в библиотеки -pg), но проблема в том, что GNU libc действительно не нравится быть статически связанным и ваш дистрибутив может не предоставить -pg скомпилированных версий каждой библиотеки, которая вам нужна.

Я предлагаю вам попробовать cachegrind, который является режимом работы valgrind и требует только отладочную информацию для всего. Это намного легче получить. Уловка в том, что у нее огромные накладные расходы; настолько велик, что это может сделать недействительным ваше тестирование. Ожидайте как минимум 2-кратное замедление.

Вы также можете попробовать perf - если вы можете получить копию в свои руки. Это очень умно, но для хакеров ядра, которые думают, что люди любят создавать вещи с нуля. Мне очень повезло с этим. (Прочтите http://web.eecs.utk.edu/~vweaver1/projects/perf-events/, который относится к базовому API, а не к утилите, но все же может спасти вас от большого количества потерянного времени.)

2 голосов
/ 14 сентября 2011

Если вы используете GCC, вам нужна опция компиляции "-pg" и приложение gprof.

1 голос
/ 05 июля 2017

Поместите это в ваш ~ / .gdbinit

define timeme
    python import time
    python starttime=time.time()
    next
    python print("Previous takes: " + (str)(time.time()-starttime) + "s")
end
document timeme
    Measure executing time of next function
    Usage: timeme or ti
end

введите timeme или ti, если вы хотите измерить время следующей функции.

1 голос
/ 14 сентября 2011

Профилирование, вероятно, то, что вы хотите. Посмотрите на prof или gprof.

ОБНОВЛЕНИЕ: После компиляции с помощью «cc -Wall -ggdb -pg -g3 -O2 diskhash.c -o diskhash» (и запуска программы), «gprof -p diskhash» дает мне:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  ms/call  ms/call  name    
 32.60      0.41     0.41        1   410.75   646.18  create_hashtab
 31.80      0.81     0.40  5087692     0.00     0.00  hash_func
 27.83      1.16     0.35  2543846     0.00     0.00  find_hash
  2.78      1.20     0.04  2543846     0.00     0.00  chop_a_line
  1.59      1.22     0.02                             main
  0.40      1.22     0.01                             frame_dummy
  0.00      1.22     0.00        4     0.00     0.00  map_da_file
...