Начиная с Delphi 6 и выше, вы можете использовать счетчик меток времени x86.
Здесь подсчитываются циклы ЦП, для процессора 1 ГГц каждый отсчет занимает одну наносекунду.
Невозможно получить более точную информацию.
function RDTSC: Int64; assembler;
asm
// RDTSC can be executed out of order, so the pipeline needs to be flushed
// to prevent RDTSC from executing before your code is finished.
// Flush the pipeline
XOR eax, eax
PUSH EBX
CPUID
POP EBX
RDTSC //Get the CPU's time stamp counter.
end;
На x64 следующий код является более точным, поскольку он не страдает от задержки CPUID
.
rdtscp // On x64 we can use the serializing version of RDTSC
push rbx // Serialize the code after, to avoid OoO sneaking in
push rax // subsequent instructions prior to executing RDTSCP.
push rdx // See: http://www.intel.de/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf
xor eax,eax
cpuid
pop rdx
pop rax
pop rbx
shl rdx,32
or rax,rdx
Используйте указанный выше код, чтобы получить метку времени до и после выполнения вашегокод.
Самый точный метод, возможный и простой как пирог.
Обратите внимание, что для получения хорошего результата необходимо выполнить тест как минимум 10 раз, при первом проходе кэш будет холодным, а случайные операции чтения и прерывания жесткого диска могут привести к потере времени.
Потому чтоэта вещь настолько точна, что может дать вам неверное представление, если вы только время первого запуска.
Почему вы не должны использовать QueryPerformanceCounter ()
QueryPerformanceCounter()
дает ту же сумму время , если процессор замедляется, это компенсирует его удушение.В то время как RDTSC даст вам такое же количество циклов, если ваш ЦП замедляется из-за перегрева или чего-то еще.
Так что, если ваш ЦП начинает сильно нагреваться и ему нужно снизить скорость, QueryPerformanceCounter()
скажет, что ваша процедура занимает больше времени (что вводит в заблуждение) и RDTSC скажет, что требуется одинаковое количество циклов (что точно) .
Это то, что вы хотите, потому что вас интересует суммациклов ЦП, которые использует ваш код, а не время настенных часов.
Из последних документов Intel: http://software.intel.com/en-us/articles/measure-code-sections-using-the-enhanced-timer/?wapkw=%28rdtsc%29
Использование тактовых сигналов процессора
Этот таймер очень точный.В системе с процессором 3 ГГц этот таймер может измерять события, которые длятся менее одной наносекунды.[...] Если частота изменяется во время работы целевого кода, окончательное чтение будет избыточным, поскольку начальные и конечные показания не были взяты с использованием одной и той же тактовой частоты. Количество тактов, которые произошли за это время, будет точным , но прошедшее время будет неизвестно.
Когда не использовать RDTSC
RDTSC полезен для базовой синхронизации.Если вы синхронизируете многопоточный код на одном процессоре, RDTSC будет работать нормально.Если у вас несколько ЦП, начальный счет может исходить от одного ЦП, а конечный - от другого.
Так что не используйте RDTSC для определения времени многопоточного кода на многопроцессорной машине.На машине с одним процессором он работает нормально, а однопоточный код на машине с несколькими процессорами - тоже нормально.
Также помните, что RDTSC считает циклы процессора.Если есть что-то, что требует времени, но не использует ЦП, например, дисковый ввод-вывод или сеть, тогда RDTSC не является хорошим инструментом.
Но в документации говорится, что RDTSC не точен для современных ЦП
RDTSC - это , а не инструмент для отслеживания времени, это инструмент для отслеживания циклов ЦП.
Для этого это инструмент only , которыйэто точно.Процедуры, которые следят за временем, не являются точными на современных процессорах, потому что часы процессора не являются абсолютными, как это было раньше.