почему перфоманс запись и аннотация не работают?

Я в тупике, я прочитал учебник по производительности и пытаюсь провести простой тест, помимо «статистики производительности», который работает. Однако первичная запись либо не работает, либо первичная аннотация не показывает записанных образцов. Запуск производительности

Например (я работаю с sudo, потому что без него я получаю кучу ошибок, которые я опубликую в конце):

sudo perf record -e cycles,instructions,cache-misses -a -c 1 ./FooExe

[ perf record: Woken up 4 times to write data ]
[ perf record: Captured and wrote 1.794 MB perf.data (~78393 samples) ]

.

sudo perf report -D -i perf.data |grep RECORD_SAMPLE |wc -l
Failed to open /tmp/perf-23796.map, continuing without symbols
20486

.

sudo perf annotate -d ./FooExe

the perf.data file has no samples! Press any key

Так что, насколько я понимаю. Я попытался перестроить perf для своей ssystem из исходников, но это тоже не помогло.

Я использую ядро ​​​​Ubuntu 14.04 3.19.0-49-generic. Это на процессоре Intel i7 I4510U. Я скомпилировал свою программу с помощью символов, но я получаю одинаковые результаты независимо от того, какое приложение я пытаюсь профилировать.

-- если я запускаю без sudo :

WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,
check /proc/sys/kernel/kptr_restrict.

Samples in kernel functions may not be resolved if a suitable vmlinux
file is not found in the buildid cache or in the vmlinux path.

Samples in kernel modules won't be resolved at all.

If some relocation was applied (e.g. kexec) symbols may be misresolved
even with a suitable vmlinux or kallsyms file.

Cannot read kernel map
Error:
You may not have permission to collect system-wide stats.
Consider tweaking /proc/sys/kernel/perf_event_paranoid:
 -1 - Not paranoid at all
  0 - Disallow raw tracepoint access for unpriv
  1 - Disallow cpu events for unpriv
  2 - Disallow kernel profiling for unpriv

person skimon    schedule 19.02.2016    source источник
comment
Я мог бы опубликовать более крупный ответ позже, но вам не нужно sudo. perf пытается включить процессорное время, проведенное в режиме ядра, в системные вызовы. Если вы пытаетесь профилировать только то, что ваш код делает в пользовательском пространстве, предупреждающее сообщение безвредно. Профилирование все еще работает. Ошибка perf report из-за того, что образцы данных принадлежат пользователю root и не читаются? Попробуйте удалить все файлы, принадлежащие root, и начать заново, вообще не используя sudo.   -  person Peter Cordes    schedule 19.02.2016
comment
хорошо спасибо. Я попытался удалить данные, принадлежащие sudo, и повторить тест. Когда я это делаю, если я пытаюсь perf annotate -d ./FooExe, тогда perf запускается, показывает индикатор выполнения и сразу же завершает работу. Если я попробую без параметра -d, он просто покажет, что в файле perf.data нет образцов.   -  person skimon    schedule 19.02.2016


Ответы (1)


Я только что попробовал вашу команду. Проблема заключалась в том, что вы использовали -a для профилирования всех процессов в масштабе всей системы, поэтому он никогда не запускал ./FooExe. Вы можете подтвердить это с помощью strace -f perf ... ./FooExe и отметить отсутствие какого-либо системного вызова execve. А также тот факт, что он возвращается мгновенно, даже если FooExe должен был занять несколько секунд.

Вот пример записи сэмплов для awk-команды Busy-loop:

perf record -e cycles,instructions,cache-misses awk 'BEGIN{for(i=0;i<40000000;i++){}}'

Теперь perf report работает. Вам не нужно указывать исполняемый файл для команды report, потому что perf.data содержит данные только для одного исполняемого файла.


Это работает так же с оболочкой ocperf.py, но вы можете записывать события для более специфичных для uarch событий. используя символические имена (вместо поиска кодов и числовых аргументов в -e):

$ ocperf.py record -e cycles,cache-misses,uops_dispatched_port.port_0 awk 'BEGIN{for(i=0;i<40000000;i++){}}'
perf record -e cycles,cache-misses,cpu/event=0xa1,umask=0x1,name=uops_dispatched_port_port_0,period=2000003/ awk 'BEGIN{for(i=0;i<40000000;i++){}}'
  (warning lines about kernel symbols)
[ perf record: Woken up 2 times to write data ]
[ perf record: Captured and wrote 0.352 MB perf.data (7819 samples) 
$ ocperf.py report
person Peter Cordes    schedule 19.02.2016
comment
спасибо, понятия не имею, почему, но я мог бы поклясться, что пробовал это раньше (без общесистемного флага), но в любом случае теперь это работает, как вы сказали. Ваше здоровье - person skimon; 19.02.2016
comment
хорошо, теперь у меня другая проблема - я получаю вывод, который не показывает мне фактические символы: например, запись ocperf.py --call-graph dwarf -e misalign_mem_ref.stores -c 1 ./a.out , затем отчет ocperf.py -g graph --no-children показывает мне 40% a.out [неизвестно] [k] 0xffffffff813b4578. Я скомпилировал с -fno-omit-frame-pointer - person skimon; 20.02.2016
comment
@skimon: Вы тоже скомпилировали с -g для полных символов отладки? Вы уверены, что вам нужно -fno-omit-frame-pointer? раскрутка стека работает без него (спасибо разделу .eh_frame_hdr, IIRC). Это нужно будет сделать только в том случае, если вы записываете обратную трассировку для каждой выборки, чтобы увидеть, являются ли звонки от одних родителей более дорогими, чем другие. IDK, если он вообще это делает; В основном я возился с изоляцией цикла, который я настраиваю, и просматривая вывод perf stat. На самом деле я не делал много записей/аннотаций. Я думаю, что обычно это просто образец указателя инструкции. - person Peter Cordes; 20.02.2016
comment
я скомпилировал с -g , у кого-то еще на SO был вопрос и ответ, предполагающий, что perf не может понять символы отладки формата dwarf, поэтому я попытался использовать соответствующие параметры записи (сейчас я забыл, но что-то вроде -g dwarf ). Во всяком случае, никаких костей на это. Другим предложением от SO был вариант указателя кадра. Символы из примера fpr стандартной библиотеки, похоже, появляются, но ничего из самого моего кода. Спасибо за помощь, в худшем случае я могу начать новый вопрос. - person skimon; 20.02.2016