⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sztimer.pas

📁 High Accuracy Timer Component
💻 PAS
字号:
unit SZTimer;

/////////////////////////////
// Version 1.1.0 
/////////////////////////////

{

 The contents of this file are subject to the Mozilla Public License
 Version 1.1 (the "License"); you may not use this file except in compliance
 with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/

 Software distributed under the License is distributed on an "AS IS" basis,
 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
 specific language governing rights and limitations under the License.

 The original code is SZTimer, released 03. May, 2005.

 The initial developer of the original code is
 Sasa Zeman (public@szutils.net, www.szutils.net)

 Copyright(C) 2005 Sasa Zeman. All Rights Reserved.
}

{--------------------------------------------------------------------

This is a high resolution timer, measures elapsed time
between start and stop.

- Milisecond duration
- CPU Clock Cycles counter

Revision History:
--------------------------------------------------------------------
Version 1.1.0, 2006-12-10
  - Added global functions to support for higher precision bechmark
    procedure SZBeforeBenchmark;
    procedure SZAfterBenchmark;

    SZBeforeBenchmark setting process priority to highest possible
    SZAfterBenchmark return it to previous

    ATTENTION!!! Enabling this feature will freeze all other
    OS processes, including systems (threads, keyboard, I/O)
    until measurement is stopped! Freezing all other processes is only
    way to make higher precision benchmark.

Version 1.0.0, 2005-05-05
  - Initial version
  - Thanks to Peter Grebenkin for creating object descendant
--------------------------------------------------------------------

  Author   : Sasa Zeman
  E-mail   : public@szutils.net or sasaz72@mail.ru
  Web site : www.szutils.net
}


interface

uses sysutils,windows, Dialogs;

type

  TSZTimer = object

    // Time start/stop
    Tstart,Tstop : Cardinal;

    // CPU counter start/stop
    Cstart,Cstop: Int64;

    ElapsedMS    : Cardinal;
    ElapsedRDTSC : Int64;

    procedure Start;
    procedure Pause;
    procedure Continue;
    procedure Stop;

    function Print: string;
    function PrintRDTSC: string;

    private
    procedure Get(var t: Cardinal);
    function  Odd(t,t1: Cardinal): Cardinal;

    procedure GetRDTSC(var c: Int64);
    function  OddRDTSC(c,c1: Int64): Int64;

  end;

function RDTSC: Int64;


var
  PerfEnd, PerfFreq, PerfStart, PerfTemp: Int64;
  PriorityClass, PriorityThread: Integer;

procedure SZBeforeBenchmark;
procedure SZAfterBenchmark;

implementation

function RDTSC: Int64;
//Returns 64-bit count of CPU clock cycles.
asm
  dw $310F  // opcode for RDTSC
end;

procedure SZBeforeBenchmark;
begin
  // Priority settings
  // Disabling will make instability

  PriorityClass := GetPriorityClass(GetCurrentProcess);
  PriorityThread:= GetThreadPriority(GetCurrentThread);

  // Set thread priority to time critical
  SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
  SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);

  // A quarter of a second for SpeedStep
  Win32Check(QueryPerformanceFrequency(PerfFreq));
  Win32Check(QueryPerformanceCounter(PerfStart));
  PerfEnd := PerfStart + (PerfFreq div 4);
  repeat
    Win32Check(QueryPerformanceCounter(PerfTemp));
  until PerfTemp >= PerfEnd;
end;

procedure SZAfterBenchmark;
begin
  // Set thread priority to previos (normal)
  SetPriorityClass(GetCurrentProcess, PriorityClass);
  SetThreadPriority(GetCurrentThread, PriorityThread);
end;

procedure TSZTimer.Get(var t: Cardinal);
begin
  t:=GetTickCount;
end;

function TSZTimer.Odd(t, t1: Cardinal): Cardinal;
begin
  Result:= t - t1;
end;

procedure TSZTimer.GetRDTSC(var c: Int64);
begin
  c:=RDTSC;
end;

function TSZTimer.OddRDTSC(c, c1: Int64): Int64;
begin
  Result:= c - c1;
end;

procedure TSZTimer.Start;
begin
  ElapsedRDTSC := 0;
  GetRDTSC(Cstart);

  ElapsedMS := 0;
  Get(Tstart);
end;

procedure TSZTimer.Pause;
begin
  GetRDTSC(Cstop);
  ElapsedRDTSC := ElapsedRDTSC + OddRDTSC(Cstop, Cstart);

  Get(Tstop);
  ElapsedMS := ElapsedMS + Odd(Tstop, Tstart);

end;

procedure TSZTimer.Continue;
begin
  Get(Tstart);
  GetRDTSC(Cstart);
end;

procedure TSZTimer.Stop;
begin
  GetRDTSC(Cstop);
  ElapsedRDTSC := ElapsedRDTSC + OddRDTSC(Cstop, Cstart);

  Get(Tstop);
  ElapsedMS := ElapsedMS + Odd(Tstop, Tstart);

  PriorityClass := GetPriorityClass(GetCurrentProcess);
  PriorityThread:= GetThreadPriority(GetCurrentThread);
end;

function TSZTimer.Print: string;
  function LeadingZero(w : Word; n: integer) : String;
  var
    s : ShortString;
  begin
    Str(w:0,s);
    s:= StringOfChar('0',n-length(s)) +s;
    result:= s;
  end;

  function TtoS(E:TFileTime):string;
  begin
    Result:=Format('%8.3f',[e.dwLowDateTime/10000000]);
  end;

var
  s: word;
  ElapSec: Real;
begin

  ElapSec:=ElapsedMS/1000;

  s:=trunc(ElapSec / 3600);
  ElapSec:=ElapSec-s*3600;
  Result:=LeadingZero(s,2)+':';

  s:=trunc(ElapSec / 60);
  ElapSec:=ElapSec-s*60;
  Result:=Result+LeadingZero(s,2)+':';

  s:=trunc(ElapSec);
  ElapSec:=ElapSec-s;
  Result:=Result+LeadingZero(s,2)+'.';

  s:=trunc(ElapSec*1000);
  Result:=Result+LeadingZero(s,3);

end;

function TSZTimer.PrintRDTSC: string;
begin
  Result:= IntToStr(ElapsedRDTSC);
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -