Я хотел бы измерить соотношение попаданий и промахов в кеше L1, L2 и L3 для некоторых частей моего кода C ++. Мне не интересно использовать Perf для всего моего приложения. Можно ли использовать Perf в качестве библиотеки внутри C ++?
int main() {
...
...
start_profiling()
// The part I'm interested in
...
end_profiling()
...
...
}
Я дал Intel PCM шанс, но у меня было две проблемы с ним. Во-первых, это дал мне несколько странных цифр. Во-вторых, он не поддерживает профилирование кеша L1.
Если это невозможно с Perf, какой самый простой способ получить эту информацию?
Похоже, все, что вы пытаетесь сделать, это прочитать несколько счетчиков перфектов, то, что PAPI Библиотека идеально подходит для.
полный список поддерживаемых счетчиков довольно долго, но звучит так, как будто тебя больше всего интересует PAPI_L1_TCM
, PAPI_L1_TCA
, и их L2
а также L3
двойники. Обратите внимание, что вы также можете разбить доступ на чтение / запись, а также различать кэши команд и данных.
Да, существует специальный мониторинг для каждого потока, который позволяет считывать счетчики перфектов из пользовательского пространства. Смотрите страницу руководства для perf_event_open(2)
поскольку perf
поддерживает только события кэша L1i, L1d и последнего уровня, которые вам необходимо использовать PERF_EVENT_RAW
режим и использовать цифры из ручного на ваш процессор.
Для реализации профилирования вам необходимо настроить sample_interval
, poll
/select
жду или жду SIGIO
сигнал, и когда это произойдет, прочитайте образец и указатель инструкции от него. Позже вы можете попытаться разрешить возвращенные указатели инструкций в именах функций, используя отладчик, такой как GDB.
Другой вариант заключается в использовании SystemTap. Вам понадобится пустая реализация start|end_profiling()
, просто чтобы включить профилирование SystemTap с чем-то вроде этого:
global traceme, prof;
probe process("/path/to/your/executable").function("start_profiling") {
traceme = 1;
}
probe process("/path/to/your/executable").function("end_profiling") {
traceme = 0;
}
probe perf.type(4).config(/* RAW value of perf event */).sample(10000) {
prof[usymname(uaddr())] <<< 1;
}
probe end {
foreach([sym+] in prof) {
printf("%16s %d\n", sym, @count(prof[sym]));
}
}