Сравнительные соображения и детерминированный сбор данных - PullRequest
1 голос
/ 15 июля 2011

Я пишу тестовую программу на С ++, которая включает в себя синхронизацию количества вызовов функций. Функции вызываются повторно и каждый раз записываются для последующего статистического анализа. Требуется, чтобы функции выполнялись одновременно в нескольких потоках и, таким образом, для обеспечения точности и справедливости эталонного теста, он запускался в операционной системе реального времени с контролируемым поведением планирования. Следующие мои проблемы:

Существуют ли детерминированные способы сбора временных данных? Я посмотрел на printf и stringstream, но ни один из них не имеет детерминированного поведения из-за операций с памятью и буфером. Они также не выполняют в O (1) по той же причине, я прав? В настоящее время я использую большой массив символов и пользовательскую функцию strcat, чтобы каждое значение времени можно было собрать в O (1). Затем этот массив печатается в конце теста, когда все данные собраны.

Я использую clock_gettime для таймингов, а clock_getres дает мне разрешение 1 нс. Можно ли доверять этому значению?

До сих пор я все делаю правильно, и есть ли другие проблемы, о которых мне следует знать при написании теста?

Ответы [ 2 ]

1 голос
/ 15 июля 2011

Вызов высокочастотных таймеров и запись сэмплов в выходной поток - это совершенно разумный способ получения данных о производительности.Но есть несколько хитрых ошибок, о которых следует позаботиться.

  • Действительно, вам не следует использовать printf и stringstream - не только потому, что время их выполнения является переменным и плохо определенным, но также потому, что онипросто чертовски медленно, особенно если вы форматируете свои данные перфоратора в строки каждую микросекунду!Гораздо лучше записать двоичные данные в предварительно выделенный буфер, например, в массив структур, а затем отформатировать их позже после завершения теста.Это будет быстрее и даст вам более согласованные накладные расходы на запись.
  • clock_gettime с таймером высокого разрешения (например, CLOCK_PROCESS_CPUTIME_ID) должно быть надежным, если человек, написавший ваше ядро, не был тупицей.Вы можете заглянуть в библиотеку Performance Application Programming Interface , если хотите запрашивать таймеры ЦП напрямую, но в этом нет необходимости.
  • Многопоточность может быть хаотической (в смысле детерминизма)) потому что потоки борются друг с другом за кеш процессора и пропускную способность памяти.Вы можете получить стохастически изменяющиеся результаты в зависимости от того, касаются ли одновременно запланированные потоки одной и той же памяти, или все время исключают работу друг друга из кэшей данных - и это будет зависеть от запуска к запуску в зависимости от того, как именно выложены данныев памяти и какие потоки работают.Но это нормально: многие технологические процессы являются стохастическими.Просто проведите тест много раз и получите статистически значимое среднее значение и отклонение для ваших показателей производительности.

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

0 голосов
/ 15 июля 2011

Do not используйте обозначение big-O для оценки реальной производительности.

Тем не менее, на остальную часть вопроса:

Сбор производительности займет некоторое время (O (1) все еще может быть значимым, просто оно не будет зависеть от ваших данных). Вам нужно сделать его максимально эффективным.

Это значит:

  1. Не для использования printf и лайков, а для записи в специальную область памяти, из которой вы извлечете данные позже.

  2. По той же причине не используйте strcat, вместо этого используйте struct s двоичных данных. Разобрать его в конце, когда вы закончите.

  3. Вместо того чтобы измерять каждый вызов, рассмотрите возможность измерения средних значений (т. Е. Измерьте не каждый вызов, а каждую 1000 и среднее значение, чтобы извлечь приблизительную стоимость одного вызова). Это уменьшит ваши накладные расходы. Это не всегда возможно, но рассмотрим это.

  4. Как правило, clock_gettime можно доверять, но это зависит от вашей ОС и оборудования - проверьте их, иногда разрешение аппаратных часов может быть не таким маленьким, как хотелось бы.

...