Уменьшение вариаций производительности в Linux - PullRequest
3 голосов
/ 26 января 2010

Я пытаюсь сравнить часть программного обеспечения, работающего на Intel Pentium с Linux поверх него. Проблема в том, что я получаю значительные колебания производительности во время последовательных тестовых прогонов, когда использую инструкцию RDTSC. Время выполнения одного и того же компонента программного обеспечения варьируется от 5 до 10 миллионов тактовых циклов, поэтому в худшем случае накладные расходы составляют 100%. Я знаю, что существуют различия в производительности, вызванные конфликтом кэша, однако, возможно, я смогу устранить другие потенциальные проблемы, такие как прерывания, другие процессы и т. Д .?

Буду благодарен за любые полезные советы, как это сделать правильно.

Большое спасибо, Kenny

Ответы [ 5 ]

4 голосов
/ 26 января 2010

Общие проблемы в этой общей области:

  • миграция процессов в многоядерных / многоядерных системах
  • RDTSC не согласован между ядрами в многопроцессорных / многоядерных системах
  • другие процессы, занимающие процессорное время (также прерывания, ввод-вывод, экранная активность и т. Д.)
  • автоматическое масштабирование тактовой частоты процессора
  • ошибки страницы VM и т. Д.

Решения:

  • Если вы выполняете однопоточный процесс в многоядерных / многоядерных системах, используйте привязку к процессору, чтобы привязать процесс к конкретному ядру. (Используйте набор задач из командной строки или вызовите sched_setaffinity () из своего кода.)

  • убедитесь, что у вас нет других процессов, занимающих процессорное время, отключите экранные заставки или другие анимации рабочего стола и убедитесь, что во время выполнения кода нет обновлений экрана. Также не используйте, например, printf в окно консоли GUI во время кодирования - сохраняйте любые результаты до тех пор, пока вы не соберете свою последнюю временную метку. (Если возможно, вы даже можете полностью убить графический интерфейс.)

  • Используйте более надежный метод синхронизации, чем RDTSC (я обычно использую clock_gettime (CLOCK_PROCESS_CPUTIME_ID, ...) в Linux).

  • Отключить автоматическое масштабирование тактовой частоты (например, Linux: cpufreq-set)

  • Запустите ваш код в цикле, скажем, для N повторов, предпочтительно повторно используя одинаковые выделения памяти для любых больших структур данных (чтобы избавиться от последствий сбоев страниц ВМ и т. Д.). Игнорировать первое измерение и усреднить оставшиеся N - 1 измерений.

0 голосов
/ 26 января 2010

Рассматривали ли вы запуск кода внутри valgrinds cachegrind или callgrind? Они должны быть в состоянии предоставить вам точное количество команд, выполнив код через valgrinds "VM".

0 голосов
/ 26 января 2010

Пожалуйста, убедитесь, что вы отключили масштабирование частоты в BIOS и операционной системе. Также звучит так, будто вы используете P4, поэтому обязательно отключите гиперпоточность.

Из-за таких вещей я сталкивался с изменениями производительности, которые вы описывали в прошлом.

Эта страница описывает, как включить на , что должно дать вам то, что вам нужно, чтобы отключить его.

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

0 голосов
/ 26 января 2010

Лучший способ уменьшить отклонения, вызванные системной средой, - запустить тест производительности в «однопользовательском» режиме, также известном как initlevel 1, или «режим восстановления».передав «-s» в качестве параметра времени загрузки ядру, или вы можете переключить на него работающую систему с помощью «init 1».

В этом режиме все демоны остановлены, и вы вошли в системукак корень.Практически все, что работает в системе, запускается с вашего интерактивного терминала.

0 голосов
/ 26 января 2010

Некоторые общие вещи: повысить приоритет процесса тестирования (man 1 nice), остановить как можно больше других процессов, выгрузить неиспользуемые модули ядра, очистить кэш диска (чтобы фоновые потоки ядра работали меньше), перезагрузиться в одиночном режиме. пользовательский режим?

...