Точная (или лучше) синхронизация процессов в микросекундах в Linux

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

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

Я помню, как это работает, хотя:

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

Обычное время процесса поддерживается с использованием обычных часов, которые, как я полагаю, имеют точность до миллисекунд (1000 Гц), что слишком велико для моих целей.

Кто-нибудь знает, о каком патче ядра я говорю? Я также помню, что это было что-то вроде слова с буквой перед или после него — что-то вроде «rtimer» или что-то в этом роде, но я точно не помню.

(Другие предложения тоже приветствуются)


Совершенно честный планировщик, предложенный Марко, — это не то, что я искал, но выглядит многообещающе. Проблема, с которой я столкнулся, заключается в том, что вызовы, которые я могу использовать для получения времени процесса, по-прежнему не возвращают достаточно детализированные значения.

  • times() возвращает значения 21, 22 в миллисекундах.
  • clock() возвращает значения 21000, 22000, с той же степенью детализации.
  • getrusage() возвращает такие значения, как 210002, 22001 (и некоторые подобные), они выглядят более точными, но значения выглядят одинаково.

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


person rix0rrr    schedule 08.10.2008    source источник
comment
Возможно, это поможет с CFS: kerneltrap.org/node/8059 Есть электронное письмо от автора, содержащий примерные инструкции по настройке.   -  person Marko Dumic    schedule 09.10.2008


Ответы (8)


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

http://icl.cs.utk.edu/papi/

person mch    schedule 30.12.2008

См. этот вопрос для получения дополнительной информации.

Что-то, что я использовал для таких вещей, это gettimeofday(). Он предоставляет структуру с секундами и микросекундами. Вызовите его перед кодом и еще раз после. Затем просто вычтите две структуры с помощью timersub, и вы сможете получить время в секундах из поля tv_usec.

person Will Mc    schedule 30.12.2008

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

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

person Stein G. Strindhaug    schedule 08.10.2008
comment
Это именно то, что я делаю, если хочу измерить скорость. Вы не говорите, какова ваша цель. Если я хочу выяснить, что нужно оптимизировать, это другая цель, чем измерение, и для нее нужны другие методы. Для этого я использую выборку стека вызовов. - person Mike Dunlavey; 30.12.2008

Я считаю, что CFC (Completely Fair Scheduler) — это то, что вам нужно.

person Marko Dumic    schedule 08.10.2008

Вы можете использовать таймер событий высокой точности (HPET), если у вас достаточно свежее ядро ​​2.6. Ознакомьтесь с Documentation/hpet.txt, чтобы узнать, как его использовать. Это решение зависит от платформы, и я считаю, что оно доступно только в более новых системах x86. HPET имеет таймер с частотой не менее 10 МГц, поэтому он должен легко соответствовать вашим требованиям.

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

person David Holm    schedule 08.10.2008

http://allmybrain.com/2008/06/10/timing-cc-code-on-linux/

может помочь вам (напрямую, если вы делаете это на C/C++, но я надеюсь, что это даст вам указатели, даже если вы этого не сделаете)... Он утверждает, что обеспечивает микросекундную точность, которая просто соответствует вашему критерию. :)

person sundar - Remember Monica    schedule 08.10.2008

Я думаю, что нашел патч ядра, который искал. Выкладываю сюда, чтобы не забыть ссылку:

http://user.it.uu.se/~mikpe/linux/perfctr/ http://sourceforge.net/projects/perfctr/

Изменить: это работает для моих целей, хотя и не очень удобно для пользователя.

person rix0rrr    schedule 19.11.2008

попробовать счетчик меток времени ЦП? Википедия предлагает использовать clock_gettime().

person Jason S    schedule 30.12.2008
comment
Вам также необходимо синхронизировать чтения TSC, чтобы предотвратить переупорядочивание инструкций, нарушающее период тестирования, наряду с обычными требованиями сходства. - person Steve-o; 31.12.2010