Как записать отметку времени каждого доступа к памяти? - PullRequest
0 голосов
/ 30 августа 2018

Есть ли способ записи каждого обращения к памяти данной программы, включая метки времени. Можно ли использовать perf для этого?

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

IntelPT будет записывать временные метки и отслеживать информацию о потоке управления работающего приложения с различными пакетами, которые будут регистрироваться в аппаратном обеспечении. Эта информация от IntelPT может затем использоваться в качестве входных данных для декодеров , что поможет получить разобранный след команд. И IntelPT также был интегрирован в perf .

Вы можете использовать perf с IntelPT в качестве событий, как показано ниже -

perf record -e intel_pt//[uk]  /bin/ls

[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.384 MB perf.data ]

Однако я бы предложил использовать PEBS (точная выборка на основе событий). PEBS (точная выборка на основе событий) - это функция, доступная для подмножества событий, которая позволяет аппаратному обеспечению собирать дополнительную информацию очень близко к точному времени, когда настроенное событие было переполнено. Вы также можете использовать PEBS с perf.

Скажем, вы хотите записать информацию, связанную с загрузкой памяти. Счетчики PEBS будут инициализированы до определенного максимального значения (которое фактически является периодом выборки). Эти счетчики будут уменьшаться на единицу при каждой загрузке памяти. Как только счетчик достигнет нуля, оборудование PEBS будет поставлено на охрану. Следующее событие загрузки памяти приведет к записи записи PEBS в буфер PEBS. Как только это происходит, счетчики PEBS автоматически сбрасываются на прежнее значение. Таким образом, период выборки 2 заставит систему записывать загрузки памяти через интервал 2.

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

Используйте PEBS в сочетании с perf для записи таких загрузок памяти -

perf record -e r81d0:pp -c 1 -d <application_name> <application_params>

r81d0: pp представляет событие загрузки памяти среди устаревших инструкций в числовой форме. В определенных случаях некоторые архитектуры ЦП не поддерживают некоторые события, и каждый вынужден использовать числовые события, подобные этому.

Однако, как сказал Питер и как было отмечено во многих других вопросах и ответах здесь, абсолютно невозможно записать 100% -ную загрузку памяти или адреса памяти без внешних аппаратных механизмов. и / или вызывая значительные накладные расходы на время выполнения.

Хотите прочитать о PEBS ?. Руководство разработчика программного обеспечения Intel станет вашим лучшим другом.

0 голосов
/ 30 августа 2018

Если вы работаете в Intel, я думаю, что функция Intel PT, упомянутая в других ответах, в сочетании с постобработкой и анализом, скорее всего, даст вам то, что вы хотите при высокой скорости (то есть что-то вроде регрессия одной цифры в производительности).

Если вы не заботитесь о производительности, вы можете использовать любое количество бинарных инструментальных сред для получения этой информации. Например, инфраструктура valgrind имеет инструмент cachegrind , который фиксирует каждый доступ к памяти и использует их для оценки поведения кэша на основе идеализированной модели кэширования.

Вы можете в значительной степени модифицировать инструмент cachegrind, чтобы выкладывать список обращений, к которым вы обращаетесь, вместе с отметкой времени. Конечно, проблема в том, что cachegrind, вероятно, работает примерно в 10 раз медленнее, чем собственное приложение, поэтому ваши временные метки будут «растянуты» и искажены (то есть, потому что разные части программы могут иметь разные накладные расходы на инструментарий).

Вопрос о том, имеет ли значение ваше заявление, зависит от вас.

Приятной особенностью Valgrind является то, что он не зависит от какого-либо конкретного оборудования и работает на разных аппаратных архитектурах. Вероятно, это также проще, чем заставить работать анализ на базе Intel PT - хотя я не уверен на 100%, так как попробовал сам.

Если вы не заботитесь об общем времени выполнения реального процесса во время записи, но вам нужны в основном точные временные показатели, вы также можете рассмотреть возможность запуска процесса под имитатором ЦП, таким как Sniper x86 simulator или gem5 , которые Питер упоминает в комментариях.

Этот сайт , который описывает инструмент CMP $ im, может быть очень полезным для вас. Он может производить трассировку обращений с помощью технологии Intel PIN , которую @Leeor также упомянул в комментариях ниже. Я рекомендую взглянуть на статьи автора, связанные с этого сайта.

0 голосов
/ 30 августа 2018

Ближайшая аппаратная возможность, о которой я могу думать, это Intel PT (трассировка процессора), которая может записывать временные метки в каждой (взятой?) Ветви, так что вы можете восстановить выполнение до блока, содержащего нагрузки. Я не использовал pt, и я не уверен, что perf может использовать его или вам нужны другие программы.

(Не совсем "базовый блок", потому что нет записи при выполнении после цели ветки где-то еще)

Это, вероятно, только тогда, когда были выданы инструкции по загрузке, а не тогда, когда их фактически запустило неупорядоченное выполнение или когда данные поступили из кеш-памяти / L1d.

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


Если вы ищете горячие точки памяти, я бы предложил профилирование с помощью perf record -e mem_load_retired.l3_miss,mem_load_retired.l2_miss или аналогичных счетчиков , чтобы искать нагрузки, которые часто пропускаются на разных уровнях кэша. Есть некоторые события магазина, но в основном для нагрузок, потому что ЦП должен ждать загрузки данных, прежде чем он сможет их использовать.

Может также dtlb_load_misses.miss_causes_a_walk или другие события TLB-пропустить.

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

Используйте perf list, чтобы увидеть события, о которых perf знает. Если ваш perf старый, вам может понадобиться оболочка ocperf.py. https://github.com/andikleen/pmu-tools

...