Накладные расходы времени _mm_lfence() недетерминированы?

Я пытаюсь определить время, необходимое для чтения элемента, чтобы убедиться, что это попадание в кеш или промах кеша. чтобы чтение было в порядке, я использую функцию _mm_lfence(). Я получил неожиданные результаты, и после проверки я увидел, что накладные расходы функции lfence не являются детерминированными. Итак, я выполняю программу, которая измеряет эти накладные расходы в цикле, например, из 100 000 итераций. Я получаю результаты более 1000 тактовых циклов за одну итерацию, а в следующий раз - 200. Что может быть причиной такой разницы между накладными расходами функции lfence, и если это настолько ненадежно, как я могу правильно оценить задержку кэш-попаданий и кэш-промахов? Я пытался использовать тот же подход, что и в этом посте: Измерение задержки памяти с помощью счетчика меток времени

код, который дает ненадежные результаты, таков:

for(int i=0; i < arr_size; i++){
  _mm_mfence();
  _mm_lfence();
   t1 = __rdtsc();
  _mm_lfence();
  _mm_lfence();
   t2 = __rdtsc();
  _mm_lfence();

   arr[i] = t2-t1;
}

значения в arr варьируются в разных диапазонах, arr_size равен 100 000.

ваш код - единственное, что работает в вашей системе? прерывания и перестановки задач могут вызвать неожиданную разницу в часах

Tom Tanner 04.02.2019 18:30

Нет, это не так, но я считаю ru_nvcsw и ru_nivcsw, которые сообщают, как часто происходило переключение контекста, равно 4. Нужно ли также проверять прерывания для этого процесса? Или как я могу это сделать?

Ana Khorguani 04.02.2019 18:48

Если вы ищете другие примеры кода для этого, проверьте github для spectre/meltdown/l1tf PoC, так как измерение времени доступа является необходимым компонентом для них.

ruthafjord 04.02.2019 22:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
3
260
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

I get results of more than 1000 clock cycle for one iteration and next time it's 200.

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

Помните, что RDTSC подсчитывает циклы ссылка (фиксированная частота, равная или близкая к максимальной нетурбо-частоте процессора), не основные такты. (холостой/турбо/любой). В старых процессорах RDTSC подсчитывал тактовые циклы ядра, но уже много лет производители процессоров имеют фиксированную частоту RDTSC, что делает ее полезной для clock_gettime(), и рекламируют этот факт с битом функции invariant_tsc CPUID. См. также Получить количество циклов процессора?

Если вы действительно хотите использовать RDTSC вместо счетчиков производительности, отключите турбо и используйте цикл прогрева, чтобы получить максимальную частоту процессора.


Существуют библиотеки, которые позволяют вам программировать счетчики производительности HW и устанавливать разрешения, чтобы вы могли запускать rdpmc в пользовательском пространстве. Это на самом деле имеет меньшие накладные расходы, чем rdtsc. См. Какой будет точный код для подсчета промахов кеша последнего уровня в архитектуре Intel Kaby Lake? для сводки способов доступа к счетчикам производительности в пользовательском пространстве.

Я также нашел документ о добавлении поддержки rdpmc в пользовательском пространстве в Linux perf (PAPI): ftp://ftp.cs.uoregon.edu/pub/malony/ESPT/Papers/espt-paper-1.pdf. IDK, если он попал в основной код ядра / производительности или нет.

Здравствуйте, я прочитал о RDTSC и думаю, что понял суть этого: «Он работает на номинальной частоте процессора». Таким образом, проблема в том, что он начинает тикать с заявленной частотой, независимой от фактической частоты процессора в данный момент. Тогда это должно означать, что проблема не в функции защиты и она занимает одинаковое время, но время измеряется неправильно.

Ana Khorguani 06.02.2019 14:16

Ну, честно говоря, у меня нет сильных предпочтений к одному конкретному способу ведения дел, я просто хочу, чтобы результат был правильным :) о «Событиях мониторинга производительности», если я не ошибаюсь, с его помощью я могу, например, прочитать количество загрузок кеша. как я видел по указанной ссылке. Но это число даст мне полное количество для процесса, возможно, не точное количество конкретных промахов и попаданий в кеш, которые меня интересуют. Или я могу настроить его так, чтобы я мог подсчитывать промахи или попадания в кеш для конкретного чтения?

Ana Khorguani 06.02.2019 14:21

@AnaKhorguani: вы можете поставить rdpmc до и после блока или отдельной инструкции и вычесть. (Вам может понадобиться lfence для предотвращения переупорядочения, я не уверен. Я не думаю, что он сериализуется в потоке инструкций.) И кстати, rdtsc правильно измеряет время. Просто время — это не то, что вам нужно, это основные тактовые циклы. (Поскольку служебные данные измерения lfence + rdtsc представляют собой постоянное количество циклов, а не наносекунд.)

Peter Cordes 06.02.2019 14:47

perf определенно поддерживает встречные запросы на основе rdpmc в пользовательском пространстве. Это самый простой способ заставить rdpmc работать в Linux.

BeeOnRope 07.02.2019 04:27

Я пытаюсь протестировать библиотеку PAPI, которую, надеюсь, правильно установил. В отдельном файле у меня есть моя программа .c, и я включаю этот заголовок #include <papi.h>. Я думаю, что это не должно быть проблемой, так как я могу определить переменную типа PAPI_event_info_t. Однако, когда я пытаюсь скомпилировать код с оператором: PAPI_library_init, я получаю сообщение об ошибке: (.text+0x41): неопределенная ссылка на `PAPI_library_init'. Я пытаюсь понять, в чем проблема, и много гуглю, но есть ли шанс, что вы могли бы предложить, как я могу скомпилировать программу с функциями библиотеки PAPI?

Ana Khorguani 07.02.2019 20:39

я должен скомпилировать с дополнительными флагами?

Ana Khorguani 07.02.2019 21:02

@AnaKhorguani: да, очевидно, вам нужна правильная опция библиотеки -l. Я тоже гуглил, но не нашел, какая библиотека на самом деле содержит функции perf.

Peter Cordes 08.02.2019 00:36

Я нашел -lpapi, и после добавления библиотеки в путь это сработало. Я могу скомпилировать и запустить программу с функциями папи, но теперь у меня другая проблема. когда я пытаюсь это сделать: if ((num_hwcntrs = PAPI_num_counters()) <= PAPI_OK) printf("Эта система имеет %d доступных счетчиков. \n", num_hwcntrs); Я понимаю, что в системе 0 доступных счетчиков. не уверен, в чем может быть проблема. думал, что опубликую это как новый вопрос

Ana Khorguani 08.02.2019 19:05

@PeterCordes, попробовав что-то, обнаружил, что количество аппаратных счетчиков на моем ноутбуке равно 0. Есть ли у меня надежда использовать papi или это тупик?

Ana Khorguani 08.02.2019 23:10

@AnaKhorguani: Вы пробовали perf stat -d ./a.out, чтобы узнать, может ли он использовать какие-либо счетчики HW? Если это работает для циклов/инструкций/и т. д., возможно, вы неправильно используете библиотеку.

Peter Cordes 09.02.2019 03:48

@PeterCordes Спасибо, ваш комментарий к другому сообщению помог. Теперь я могу больше тестировать с помощью papi и, надеюсь, смогу получить более точные результаты для промахов и попаданий в кэш процессора.

Ana Khorguani 09.02.2019 21:31

Другие вопросы по теме

Как сохранить модель машинного обучения Spacy в приложении Django
Должен ли я считать статическую копию дорогостоящей?
Не удается найти загруженное приложение при поиске по имени или имени пакета
Оптимизация запросов к словарю MySQL
Оптимизация сопоставления элементов из двух больших наборов данных с использованием расстояния Левенштейна (сравнение каждого элемента друг с другом)
Почему время доступа к памяти увеличивается, когда размер кеша ЦП намного превышает размер
Как x86 bsr/bsf может иметь фиксированную задержку, не зависящую от данных? Разве он не перебирает биты, как показывает псевдокод?
Каков эффективный способ найти минимальную сумму нескольких значений словаря, учитывая ключи взаимоисключающих целых чисел?
Производительность: создавать индексы после или до преобразования из UNLOGGED в LOGGED?
Алгоритм для создания массива с длиной n и количеством инверсий k за время O (n log n)?