Sample.pas

{$N+} procedure ReadTSC(Var counter: Comp); far; external;{$L tsc.obj} Var a1, a2, a3: Comp;begin ReadTSC(a1); Writeln('Working:)'); { <--- Засекаем время выполнения этой строки } ReadTSC(a2); Writeln(a1:20:0, ', ', a2:20:0, ', ', (a2-a1):20:0)end.

Примечание:

В 32-битном компиляторе FPC (да и в Дельфи тоже) этот же метод реализуется немного по-другому:

function rdtsc:Int64;asm rdtsc mov dword ptr [Result], eax mov dword ptr [Result + 4], edxend; var Start, Finish, Duration:Int64; begin Start:= rdtsc; writeln('test'); // Посмотрим, за сколько тактов выполняется WriteLn Finish:= rdtsc; Duration:= (Finish - Start); WriteLn('Время выполнения (в тактах) = ', Duration);end.


Использование GetTickCount() (32-битные компиляторы)

При использовании 32-битных компиляторов для определения времени выполнения можно использовать функцию GetTickCount(), возвращающую количество миллисекунд, прошедших с момента старта системы. Разумеется, в случае использования GetTickCount проблема с переменой даты не возникает, но тут нас подстерегает другая опасность: каждые 49,8 дней будет происходить целочисленное переполнение этого значения, так что есть небольшая опасность, что если вызвать функцию незадолго до этого события один раз, а затем второй раз - после, то получится неизвестно что, а именно: число, близкое к -2*MaxInt.

Использование:

uses Windows;var Duration: Cardinal; begin Duration:= GetTickCount();... // замеряемый блок Duration:= GetTickCount() - Duration; WriteLn('Время выполнения = ', Duration);end.

Этот метод также не отличается особой точностью (предельно малые интервалы времени при использовании GetTickCount() составляют 10.. 16 мс), но зато он очень прост, и если очень высокая точность не нужна - очень даже имеет право на существование.


Использование QueryPerformanceCounter() (32-битные компиляторы)

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

Используется QueryPerformanceCounter вот так:

Uses Windows, SysUtils;Var t1, t2, Res: int64; bOk: BOOL; Procedure StartTimer;Begin t1:= 0; t2:= 0; Res:= 0; bOK:= QueryPerformanceFrequency(Res); If bOK Then QueryPerformanceCounter(t1); end; Procedure StopTimer;Begin If bOK Then QueryPerformanceCounter(t2);End; { Время выполнения этой процедуры будет засекаться }Procedure SomeProc;Var i: Integer; a, b, T: Integer;Begin For i:= 1 To 10000 Do Begin a:= 100; b:= 250; T:= a; a:= b; b:= T; End;End; Procedure CheckExecutionTime;Begin StartTimer; SomeProc; // Запускаем тестируемую процедуру StopTimer; If bOK Then Writeln('Execution time: ' + Format('%g sec.',[(t2 - t1) / Res]));End; { Изменяем приоритет потока на TIME_CRITICAL для увеличения точности }Procedure Check_Time;Var tp, pc: DWORD;Begin tp:= GetThreadPriority(GetCurrentThread()); pc:= GetPriorityClass(GetCurrentProcess()); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); Try CheckExecutionTime() Finally SetThreadPriority(GetCurrentThread(), tp); SetPriorityClass(GetCurrentProcess(), pc); EndEnd; { Основная программа }begin check_time();end.

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: