Ответ 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.
Наконец, вот список ссылок, которые я нашел полезными в дополнение к ссылкам выше:
- http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
- Как измерить ACTUAL время выполнения программы C под Linux?
- http://digitalsandwich.com/archives/27-benchmarking-misconceptions-microtime-vs-getrusage.html
- http://www.unix.com/hp-ux/38937-getrusage.html
Обновление: для OS X, clock_gettime
реализовано с 10.12 (Sierra). Кроме того, как платформы POSIX, так и BSD (например, OS X) разделяют поле структуры rusage.ru_utime
.