std::chrono::clock, аппаратные часы и счетчик циклов

std::chrono предлагают несколько часов для измерения времени. В то же время, я думаю, единственный способ, которым процессор может оценить время, — это подсчет циклов.

Вопрос 1. Есть ли у ЦП или ГП какой-либо иной способ оценки времени, кроме подсчета циклов?

Если это так, то, поскольку циклы счета компьютера никогда не будут такими точными, как атомные часы, это означает, что «секунда» (period = std::ratio<1>) для компьютера может быть на самом деле короче или больше, чем реальная секунда, вызывая различия в длительный период измерения времени между компьютерными часами и, скажем, GPS.

Вопрос 2. Это правильно?

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

Вопрос 3. Измеряется ли "количество циклов" процессора и видеокарты в зависимости от аппаратной частоты? Если да, то как std::chrono с этим бороться? Если нет, то чему соответствует цикл (например, что такое «основное» время)? Есть ли способ получить доступ к преобразованию во время компиляции? Есть ли способ получить доступ к преобразованию во время выполнения?


person Vincent    schedule 15.06.2018    source источник
comment
superuser.com/questions/253471 /   -  person Ripi2    schedule 16.06.2018
comment
Между прочим, все современные часы работают, отсчитывая регулярно происходящие события. Эта тенденция началась в 1656 году с первых маятниковых часов, которые отсчитывали колебания колеблющегося маятника. Со временем это изменило бы то, что считалось вибрациями кристаллов кварца и, в конечном счете, вибрациями атомов. Но основное измерение времени с помощью методологии подсчета оставалось постоянным на протяжении веков. ЗА ИСКЛЮЧЕНИЕМ: Последнее достижение состоит в том, чтобы одни часы спрашивали у другой группы часов, который час, вели об этом разговор и сходились к единому мнению о правильном времени. Например. это НТП.   -  person Howard Hinnant    schedule 16.06.2018


Ответы (2)


Циклы подсчета, да, но циклы чего?

В современном x86 источник времени, используемый ядром (внутренне, а также для clock_gettime и других системных вызовов), обычно представляет собой счетчик с фиксированной частотой, который подсчитывает «опорные циклы» независимо от режима турбо, энергосбережения или простоя с остановкой часов. (Это счетчик, который вы получаете от rdtsc или __rdtsc() в C/C++. ).

Обычные реализации std::chrono будут использовать предоставляемую ОС функцию, такую ​​как clock_gettime в Unix. (В Linux это может выполняться исключительно в пользовательском пространстве, код + данные масштабного коэффициента на странице VDSO, отображаемой ядром в адресное пространство каждого процесса. очень помогает с включенным смягчением последствий Meltdown + Spectre.)

Профилирование жесткого цикла, не привязанного к памяти, может потребовать использования фактических тактов ядра, поэтому оно будет нечувствительным к фактической скорости текущего ядра. (И не нужно беспокоиться о разгоне процессора до максимального турбо и т. Д.), Например. используя perf stat ./a.out или perf record ./a.out. например Может ли MOV x86 действительно быть бесплатным? ? Почему я вообще не могу это воспроизвести?


Некоторые системы не имеют счетчика, эквивалентного настенным часам, встроенного прямо в ЦП, поэтому либо ОС будет поддерживать время в ОЗУ, которое она обновляет при прерываниях таймера, либо функции запроса времени будут считывать время. с отдельного чипа.

(Системный вызов + аппаратный ввод-вывод = более высокие накладные расходы, что является одной из причин того, что инструкция x86 rdtsc превратилась из вещи профилирования в вещь источника синхронизации.)

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

person Peter Cordes    schedule 16.06.2018

Вопрос 1: Есть ли у ЦП или ГП какой-либо другой способ оценки времени, кроме подсчета циклов?

Разное оборудование может предоставлять разные возможности. Например, ПК с архитектурой x86 использовали несколько аппаратных средств для синхронизации: за последнее десятилетие или около того процессоры с архитектурой x86 имеют Time Stamp. Счетчики работают на своей частоте обработки или, в последнее время, на некоторой фиксированной частоте (постоянная скорость, также известная как инвариантный TSC); там может быть таймер событий высокой точности, и, если вернуться назад, были программируемые таймеры прерывания (https://en.wikipedia.org/wiki/Programmable_interval_timer).

Если это так, то, поскольку способ счета циклов компьютера никогда не будет таким точным, как атомные часы, это означает, что секунда (период = std::ratio‹1›) для компьютера может быть на самом деле короче или больше, чем фактическая секунда, вызывая различия в долгосрочном измерении времени между компьютерными часами и, скажем, GPS.

Да, компьютер без атомных часов (сейчас они доступны на чипе) не будет таким точным, как атомные часы. При этом такие службы, как сетевой протокол времени, позволяют поддерживать более тесную согласованность между несколькими компьютерами. . Иногда этому помогает использование методов Pulse Per Second (PPS). Более современные и точные варианты включают протокол точного времени (PTP) (который часто может достигать менее микросекунды). точность по локальной сети).

Вопрос 3: Измеряется ли количество циклов ЦП и ГП в зависимости от аппаратной частоты?

Это зависит. Для TSC более новые реализации TSC с постоянной скоростью не изменяются, другие изменяются.

Если да, то как с этим справляется std::chrono?

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

Если нет, то чему соответствует цикл (например, каково основное время)?

Для процессоров Intel см. этот ответ.

Есть ли способ получить доступ к преобразованию во время компиляции? Есть ли способ получить доступ к преобразованию во время выполнения?

std::chrono::duration::count показывает количество тиков для любого используемого источника времени, и вы может duraction_cast в другие единицы времени (например, секунды). Ожидается, что C++20 представит дополнительные возможности, такие как clock_cast. Насколько я знаю, constexpr преобразование недоступно: тоже кажется сомнительным, если программа может в конечном итоге работать на машине с другой скоростью TSC, чем машина, на которой она была скомпилирована.

person Tony Delroy    schedule 16.06.2018