Июль-Декабрь 2020 — Заметка №8

Одна из вещей, которые мы воспринимаем как краеугольный камень мира, — всеобщая синхронизация времени. Большинство людей на планете синхронизированы по отношению к координате времени: они называют каждый момент времени одинаково, они могут выполнять действия одновременно. У меня сейчас 22:36, в Москве 21:36, а в Сан-Диего 11:36 — но это все разные символы одной точки, одного момента.

Подобная синхронизация это недавнее приобретение. Каких-то несколько сотен лет назад этого не было. Было локальное время в каждом городе, округе — но оно не было синхронизировано с остальными людьми.

Подобная синхронизация важна. От неё зависит работа многих систем, которые ожидают, что время везде одинаково. Раньше был сигнал точного времени каждый день, который всех синхронизировал. Cейчас системы могут, например, узнавать точное время по интернету через протокол Network Time Protocol (NTP) у специальных серверов. Но как получить точное время, если запрос в интернете может занять какое-то непонятное время?

Рассмотрим например вот такую ситуацию. Где-то в глухой тайге есть деревня А. В деревне есть одни часы. Часы иногда начинают отставать или спешить и надо их время от времени поправлять.

К счастью рядом есть другая деревня Б в которой есть не только часы, но и радио. По радио передают сигнал точного времени раз в день, поэтому в этой деревни часы всегда точные.

Время от времени деревня А выбирает человека и отправляет его в деревню Б узнать точное время. В зависимости от того, кого выбрали, от погоды и сезона, путь может занять от нескольких часов до половины дня. То есть человек может запомнить точное время на момент, когда она или она были в деревне Б. Но после этого ему надо вернутся обратно, а путь занимает какое-то время (каждый раз разное) и у человека нет своих часов.

Вопрос — как в таких условиях деревня А может узнавать точное время? (предлагаю читателю поразмыслить над этим пару минут)

Подход тут на самом деле элегантен и прост. Ниже я его вкратце и упрощенно опишу.

Для получения точного времени посланец должен запоминать и записывать не только точное время в деревне Б, но и время каждого момента этого пути. При выходе посланец записывает время по неправильным часам деревни А (время t1). При приходу в деревню Б — записывает точное время прихода в деревню Б по точным часам деревни Б(время t2). При выходе из деревни Б — точное время выхода (время t3). И при возвращении в деревню А — время возврата по неправильным часам А (t4).

Когда у нас есть эти четыре точки, то это означает, что мы можем рассчитать среднее время в пути. Это ((t4-t1)-(t3-t2)) / 2.

То есть всё время, пока посланец не был в деревне А минус время, которое он провел в деревне Б. Нам не важно, что t4/t1 и t2/t3 измерены на разных часах с немного разным временем, так мы оперируем разницей во времени, а не абсолютными значениями. Зная среднее время в пути мы можем посчитать ошибку часов А. Это t2-t1-ВремяВПути. Если часы показывают одинаковое время, то t1+ВремяВПути было бы равно t2 (время старта + время в пути = время прихода). Но так как полученное время прихода по часам Б — другое, то эта разница и есть ошибка часов А.

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

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

Картинка показывает то же самое на простом примере. (одна клеточка = 1 секунда)