Время измерения в Linux - время против часов против getrusage vs clock_gettime vs gettimeofday vs timespec_get?

Среди функций синхронизации time, clock getrusage, clock_gettime, gettimeofday и timespec_get я хочу четко понимать, как они реализованы и каковы их возвращаемые значения, чтобы знать в какой ситуации я должен их использовать.

Сначала нам нужно классифицировать функции, возвращающие значения wall-clock, сравнивая функции, возвращающие значения процессов или потоков. gettimeofday возвращает значение настенного времени, clock_gettime возвращает значение времени настенного времени или или значения потоков в зависимости от параметра clock, переданного ему. getrusage и clock возвращают значения процесса.

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

Кажется, что getrusage использует только галочку ядра (обычно 1 мс) и, как следствие, не может быть более точным, чем мс. Это правильно? Тогда функция getimeofday, по-видимому, использует наиболее точные базовые аппаратные средства. Как следствие, его точность, как правило, микросекунды (не может быть больше из-за API) на последних аппаратных средствах. Что насчет clock, на странице руководства говорится о "приближении", что это значит? Что насчет clock_gettime, API находится в наносекундах, означает ли это, что он может быть настолько точным, если это позволяет его базовое оборудование? Как насчет монотонности?

Существуют ли какие-либо другие функции?

Ответ 1

Проблема заключается в том, что в C и С++ существует несколько различных временных функций, и некоторые из них различаются по поведению между реализациями. Есть также много полуответчиков, плавающих вокруг. Компиляция списка функций часов вместе со своими свойствами ответит на вопрос правильно. Для запуска задайте вопрос о том, какие соответствующие свойства мы ищем. Глядя на ваш пост, я предлагаю:

  • Какое время измеряется часами? (реальный, пользователь, система или, надеюсь, нет, настенные часы?)
  • Какова точность часов? (s, ms, μs или быстрее?)
  • После того, сколько времени часы обтекают? Или есть какой-то механизм, чтобы избежать этого?
  • Является ли монотонным часы или будет изменяться с изменениями в системном времени (через NTP, часовой пояс, летнее время, пользователем и т.д.)?
  • Как вышеизложенное отличается от реализаций?
  • Является ли конкретная функция устаревшей, нестандартной и т.д.?

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

Вот что я нашел до сих пор для часов в Linux и OS X:

  • time() возвращает время на стене с ОС с точностью в секундах.
  • clock(), похоже, возвращает сумму пользовательского и системного времени. Он присутствует на C89 и позже. В свое время это должно было быть временем процессора в циклах, но современные стандарты как POSIX требуют, чтобы CLOCKS_PER_SEC был 1000000, давая максимально возможную точность 1 мкс. Точность моей системы действительно равна 1 мкс. Эти часы обтекают один раз, когда он заканчивается (это обычно происходит после ~ 2 ^ 32 тиков, что не очень велико для тактовой частоты 1 МГц). man clock говорит, что с glibc 2.18 он реализован с помощью clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) в Linux.
  • clock_gettime(CLOCK_MONOTONIC, ...) обеспечивает наносекундное разрешение, является монотонным. Я считаю, что "секунды" и "наносекунды" хранятся отдельно, каждый в 32-битных счетчиках. Таким образом, любое обертывание будет происходить после многих десятилетий безотказной работы. Это похоже на очень хорошие часы, но, к сожалению, он еще не доступен на OS X. POSIX 7 описывает CLOCK_MONOTONIC как необязательное расширение.
  • getrusage() оказался лучшим выбором для моей ситуации. Он сообщает о времени пользователя и системы отдельно и не обходит. Точность в моей системе составляет 1 мкс, но я также тестировал ее в системе Linux (Red Hat 4.1.2-48 с GCC 4.1.2), и точность была всего 1 мс.
  • gettimeofday() возвращает время настенных часов с (номинально) точностью μs. В моей системе эти часы, похоже, имеют точность μs, но это не гарантируется, потому что "разрешение системных часов зависит от оборудования" . POSIX.1-2008 говорит, что. "Приложения должны использовать функцию clock_gettime() вместо устаревшей функции gettimeofday()", поэтому вам следует держаться подальше от нее. Linux x86 и реализует его как системный вызов.
  • mach_absolute_time() - это опция для очень высокого разрешения (ns) для OS X. В моей системе это действительно дает разрешение ns, В принципе, эти часы обтекают, однако они сохраняют ns, используя 64-разрядное целое число без знака, поэтому обертка вокруг не должна быть проблемой на практике. Переносимость сомнительна.
  • Я написал гибридную функцию на основе этого фрагмента, который использует clock_gettime при компиляции на Linux или таймер Mach при компиляции на OS X, чтобы получить точность ns как для Linux, так и для OS X.

Все вышеперечисленное существует как в Linux, так и в OS X, если не указано иное. "Моя система" в приведенном выше примере - это Apple, работающая под управлением OS X 10.8.3 с GCC 4.7.2 от MacPorts.

Наконец, вот список ссылок, которые я нашел полезными в дополнение к ссылкам выше:


Обновление: для OS X, clock_gettime реализовано с 10.12 (Sierra). Кроме того, как платформы POSIX, так и BSD (например, OS X) разделяют поле структуры rusage.ru_utime.

Ответ 2

C11 timespec_get

Пример использования: fooobar.com/info/9684/...

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

Он возвращает время стены, а не использование ЦП.

glibc 2.21 реализует его под sysdeps/posix/timespec_get.c, и он пересылает непосредственно:

clock_gettime (CLOCK_REALTIME, ts) < 0)

clock_gettime и CLOCK_REALTIME являются POSIX http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html, а man clock_gettime говорит, что эта мера может иметь разрывы, если вы меняете некоторое время установки системы во время вашей программы.

С++ 11 chrono

Поскольку мы находимся в этом, пусть они также охватывают их: http://en.cppreference.com/w/cpp/chrono

GCC 5.3.0 (С++ stdlib находится внутри источника GCC):

  • high_resolution_clock является псевдонимом для system_clock
  • system_clock переходите к первому из следующих доступных:
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock переходите к первому из следующих доступных:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

Отвечено на вопрос: Разница между std:: system_clock и std:: stable_clock?

CLOCK_REALTIME vs CLOCK_MONOTONIC: Разница между CLOCK_REALTIME и CLOCK_MONOTONIC?