Как микросекундное время linux gettimeofday() получается и какова его точность?
Время настенных часов обычно предоставляется системами RTC. Это в основном обеспечивает время до миллисекунд и обычно имеет гранулярность 10-20 миллисекунд. Однако часто сообщается, что разрешение / детализация gettimeofday() находится в диапазоне нескольких микросекунд. Я предполагаю, что микросекундная гранулярность должна быть взята из другого источника.
Как достигается микросекундное разрешение / гранулярность gettimeofday()?
Когда часть с точностью до миллисекунды берется из RTC, а микросекунды снимаются с другого оборудования, возникает проблема с фазировкой двух источников. Два источника должны быть synchronized
как-то.
Как осуществляется синхронизация / фазировка между этими двумя источниками?
Изменить: Из того, что я прочитал в ссылках, предоставленных amdn, в частности по следующей ссылке Intel, я бы добавил вопрос здесь:
Естьли gettimeofday()
обеспечить разрешение / детализацию в микросекундном режиме вообще?
Редактировать 2: Обобщая ответ amdns с еще некоторыми результатами чтения:
Linux использует только часы реального времени (RTC) во время загрузки для синхронизации со счетчиком с более высоким разрешением, например Timestampcounter (TSC). После загрузки gettimeofday()
возвращает время, которое полностью основано на значении TSC и частоте этого счетчика. Начальное значение для TSCfrequency
корректируется / калибруется путем сравнения системного времени с внешним источником времени. Регулировка выполняется / настраивается функцией adjtimex(). Ядро использует петлю фазовой синхронизации, чтобы гарантировать, что результаты времени являются монотонными и последовательными.
Таким образом, можно сказать, чтоgettimeofday()
имеет микросекундное разрешение. Принимая во внимание, что более современные Timestampcounter работают в режиме ГГц, достижимое разрешение может быть в режиме наносекунд. Поэтому этот содержательный комментарий
/**
407 * do_gettimeofday - Returns the time of day in a timeval
408 * @tv: pointer to the timeval to be set
409 *
410 * NOTE: Users should be converted to using getnstimeofday()
411 */
можно найти в Linux / kernel / time / timekeeping.c. Это говорит о том, что в более поздний момент времени возможно будет доступна функция с еще более высоким разрешением. Прямо сейчасgetnstimeofday()
доступно только в пространстве ядра.
Тем не менее, просматривая весь код, чтобы понять это правильно, вы увидите довольно много комментариев о неопределенности. Возможно получить микросекундное разрешение. Функцияgettimeofday()
может даже показать зернистость в микросекундном режиме. Но: есть серьезные сомнения по поводу его точности, потому чтоdrift
частоты TSC не может быть точно скорректирована для. Кроме того, сложность кода, касающегося этого вопроса в Linux, является намеком на то, что на самом деле слишком сложно сделать это правильно. Это особенно, но не только из-за огромного количества аппаратных платформ, на которых Linux должна работать.
Результат: gettimeofday()
возвращает монотонное время с микросекундной гранулярностью, но время, которое оно обеспечивает, почти никогда не является фазой one microsecond
с любым другим источником времени.
2 ответа
Как достигается микросекундное разрешение / гранулярность gettimeofday()?
Linux работает на разных аппаратных платформах, поэтому особенности отличаются. На современной платформе x86 Linux использует счетчик меток времени, также известный как TSC
, который приводится в действие несколькими кварцевыми генераторами, работающими на частоте 133,33 МГц. Кристаллический генератор обеспечивает процессор эталонным тактовым сигналом, а процессор умножает его на несколько кратных - например, на процессоре 2,93 ГГц кратное число равно 22. TSC
Исторически это был ненадежный источник времени, потому что реализации останавливали счетчик, когда процессор переходил в спящий режим, или потому, что множитель не был постоянным, поскольку процессор сдвигал множители для изменения состояния производительности или снижения производительности, когда он нагревался. Современные процессоры x86 обеспечивают TSC
это постоянно, инвариантно и безостановочно. На этих процессорах TSC
Это отличные часы с высоким разрешением, и ядро Linux определяет начальную приблизительную частоту во время загрузки. TSC
обеспечивает микросекундное разрешение для системного вызова gettimeofday() и наносекундное разрешение для системного вызова clock_gettime().
Как осуществляется эта синхронизация?
Ваш первый вопрос был о том, как часы Linux обеспечивают высокое разрешение, второй вопрос о синхронизации, это различие между точностью и точностью. В большинстве систем есть часы с резервным питанием от батареи, чтобы сохранять время суток при выключении системы. Как и следовало ожидать, эти часы не обладают высокой точностью или точностью, но при запуске системы они получат время суток "на стадионе". Для обеспечения точности большинство систем используют дополнительный компонент для получения времени от внешнего источника в сети. Два общих из них
Эти протоколы определяют главные часы в сети (или уровень часов, полученных из атомных часов), а затем измеряют задержки в сети для оценки смещений от главных часов. Как только смещение от мастера определено, системные часы disciplined
чтобы держать это точно. Это может быть сделано
- Шагать по часам (относительно большая, резкая и нечастая настройка времени), или
Slewing
часы (определяемые как частота тактовой частоты, которая должна быть скорректирована путем медленного увеличения или уменьшения частоты за определенный период времени)
Ядро предоставляет системный вызов adjtimex, чтобы разрешить синхронизацию часов. Подробнее о том, как современные многоядерные процессоры Intel поддерживают синхронизацию TSC между ядрами, см. В разделе Процесс извлечения CPU TSC, особенно в многоядерной и многопроцессорной среде.
Соответствующие исходные файлы ядра для настройки часов: kernel / time.c и kernel / time / timekeeping.c.
Когда Linux запускается, он инициализирует программные часы, используя аппаратные часы. См. Главу Как Linux отслеживает время в часах HOWTO.