Во-первых, вы должны учитывать, что perf
на самом деле не измеряет время - он записывает события. Теперь вы можете выполнить некоторое профилирование, просмотреть стеки вызовов и получить некоторую информацию об инициализации, но для измерения определенного времени нам нужно записать начальную и конечную временную метку.
В случае время достижения функции main
, мы можем использовать
1) Динамическую точку трассировки на main
:
$ sudo perf probe -x ./gctor main Added new event: probe_gctor:main (on main in ./gctor)
Теперь вы можете использовать ее во всех инструментах перфорации,например:
perf record -e probe_gctor:main -aR sleep
Для этого требуются довольно высокие привилегии, в этом примере я просто использую root.
2) Разумная точка для "запуска" вашего двоичного файла.
Я предлагаю точку трассировки syscalls:sys_exit_execve
. Это в основном сразу после того, как perf record
начал выполнять ваш двоичный файл. Это работает в моей версии (5.3.7) - если это не для вас, вам, возможно, придется повозиться. Конечно, вы могли бы просто использовать -e cycles
, но потом вы получите спам с событиями, которые вам не нужны.
Соберите все вместе:
sudo perf record -e probe_gctor:main -e syscalls:sys_exit_execve ./gctor
^ this is what perf probe told you earlier
И затем посмотрите на это с помощьюperf script --header
# time of first sample : 77582.919313
# time of last sample : 77585.150377
# sample duration : 2231.064 ms
[....]
# ========
#
gctor 238828 [007] 77582.919313: syscalls:sys_exit_execve: 0x0
gctor 238828 [001] 77585.150377: probe_gctor:main: (5600ea33414d)
Вы можете либо вычислить его по этим двум выборкам, либо использовать sample duration
, если в вашей трассе действительно только два образца.
Для полноты: Вотспособ сделать это с помощью gdb
:
gdb ./gctor -ex 'b main' -ex 'python import time' -ex 'python ts=time.time()' -ex 'run' -ex 'python print(time.time()-ts)'
Это гораздо менее точно, с нагрузкой в моей системе около 100 мс, но не требует более высоких привилегий. Конечно, вы могли бы улучшить это, просто создав собственного бегуна с fork/ptrace/exec
в C.