Измерять время в функции в C

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

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

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

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

5 ответов

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

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

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

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

У меня есть вспомогательная функция в моем ~/.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)

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

Поместите это в ваш ~/.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 когда вы хотите измерить время следующей функции.

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

ОБНОВЛЕНИЕ: После компиляции с "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
Другие вопросы по тегам