Я собираюсь встречаться с различными деталями в этом ответе, но какого черта ...
Мне пришлось решать эту проблему несколько лет назад на ПК под управлением Windows, поэтому я имел дело с процессорами Intel серии x86, такими как 486, Pentium и так далее. Стандартным алгоритмом в этой ситуации было выполнение длинного ряда инструкций DIVide, потому что они, как правило, являются наиболее привязанными к процессору одиночными инструкциями в наборе Intel. Таким образом, предварительная выборка из памяти и другие архитектурные проблемы не оказывают существенного влияния на время выполнения инструкции - очередь предварительной выборки всегда заполнена, а сама инструкция не затрагивает никакую другую память.
Вы бы рассчитывали время, используя часы с наивысшим разрешением, к которым вы могли бы получить доступ в среде, в которой вы работаете. (В моем случае я работал почти во время загрузки на ПК, совместимом, поэтому я непосредственно программировал микросхемы таймера на Материнская плата. Не рекомендуется в реальной ОС, обычно есть какой-то подходящий API для вызова в эти дни).
Основная проблема, с которой вам приходится сталкиваться - это разные типы процессоров. В то время Intel, AMD и некоторые мелкие производители, такие как Cyrix, делали процессоры x86. У каждой модели были свои рабочие характеристики по сравнению с инструкцией DIV. Моя функция синхронизации сборки будет просто возвращать количество тактовых циклов, выполненных определенным фиксированным количеством инструкций DIV, выполненных в узком цикле.
Итак, я собирал некоторые временные значения (необработанные возвращаемые значения из этой функции) с реальных ПК, на которых работала каждая модель процессора, и записывал их в электронную таблицу в соответствии с известной частотой процессора и типом процессора. На самом деле у меня был инструмент командной строки, который представлял собой лишь тонкую оболочку вокруг моей функции синхронизации, и я брал диск в компьютерные магазины и получал время от моделей дисплея! (Я работал в очень маленькой компании в то время).
Используя эти необработанные тайминги, я мог построить теоретический график того, какие тайминги я должен получить для любой известной скорости этого конкретного процессора.
Здесь был трюк: я всегда ненавидел, когда вы запускаете утилиту, и она объявляет, что ваш процессор имеет частоту 99,8 МГц или что-то в этом роде. Ясно, что это было 100 МГц, и в измерении была только небольшая ошибка округления. В своей таблице я записал фактические скорости, которые продавались каждым поставщиком процессоров. Затем я бы использовал график фактического времени для оценки прогнозируемого времени для любой известной скорости. Но я бы построил таблицу точек вдоль линии, где время должно округляться до следующей скорости.
Другими словами, если 100 тиков для выполнения этого повторяющегося деления означают 500 МГц, а 200 тиков означают 250 МГц, то я построю таблицу, в которой будет сказано, что все, что ниже 150, будет 500 МГц, а что-нибудь выше, чем 250 МГц. , (Предполагая, что это были только две скорости, доступные от этого производителя чипов). Это было хорошо, потому что, даже если какой-то странный кусок программного обеспечения на ПК сбрасывал мои тайминги, конечный результат часто был бы мертвым.
Конечно, сейчас, в наши дни разгона, динамических тактовых частот для управления питанием и других подобных хитростей, такая схема была бы гораздо менее практичной. По крайней мере, вам нужно что-то сделать, чтобы убедиться, что ЦП достиг максимальной динамически выбранной скорости, прежде чем запускать функцию синхронизации.
Хорошо, я сейчас вернусь к тому, чтобы прогонять детей с моей лужайки.