Сравнение значений System.nanoTime(), полученных на разных компьютерах

Правильно ли сравнивать два значения в результате вызова System.nanoTime() на двух разных машинах? Я бы сказал нет, потому что System.nanoTime() возвращает время с точностью до наносекунды относительно некоторого произвольного момента времени, используя счетчик меток времени (TSC), который зависит от процессора.

Если я прав, есть ли способ (в Java) захватить мгновение на двух разных машинах и сравнить (безопасно) эти значения с точностью не менее микросекунды или даже с точностью до нанометра?

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

4 ответа

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

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

Вы не можете использовать nanoTime между двумя разными машинами. Для документации по API Java:

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

Там нет никакой гарантии, что nanoTime относительно любой временной базы.

Вы можете синхронизировать время с текущим временем миллис. Однако даже если вы используете NTP, это может дрейфовать от 1 мс до 10 мс между машинами. Единственный способ обеспечить микросекундную синхронизацию между компьютерами - это использовать специализированное оборудование.

nanoTime гарантированно определяется одинаково или имеет одинаковое разрешение на двух разных ОС.

Это зависит от процессора и ОС. Если посмотреть на часы POSIX, например, существуют метки времени с высокой точностью времени суток (например, CLOCK_REALTIME возвращает значение времени нано эпохи) и метки времени произвольной времени высокой точности (например, CLOCK_MONOTONIC) (NB: Разница между этими 2 хорошо объяснена в этом ответе).

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

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

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

Другие вопросы по тегам