Измерять время в функции в 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