unit ZTimer;
interface
uses
WinApi.Windows;
type
TZTimer = packed record
private
FStart: UInt64;
FEnd: UInt64;
FSEC: Double;
FMSEC: Double;
public
procedure Init;
procedure Reset;
procedure Start;
procedure Stop;
function TimeInSec: Double;
function TimeInMSec: Double;
end;
var
AuxTimer: TZTimer;
FpsTimer: TZTimer;
SortTimer: TZTimer;
implementation
procedure TZTimer.Init;
{$IFDEF WIN32}
var
Freq: UInt64;
begin
QueryPerformanceFrequency(Freq);
FSEC := (1.0 / Freq);
FMSEC := (1.0 / Freq) * 1000.0;
end;
{$ENDIF}
{$IFDEF WIN64}
const
D0: Double = 1.0;
D1: Double = 1000.0;
asm
.NOFRAME
lea r8, self.FSEC
lea r9, self.FMSEC
sub rsp, 8
lea rcx, [rsp]
call QueryPerformanceFrequency
mov rax, [rsp]
add rsp, 8
cvtsi2sd xmm1, rax
movsd xmm0, [D0]
divsd xmm0, xmm1
movsd [r8], xmm0
mulsd xmm0, [D1]
movsd [r9], xmm0
end;
{$ENDIF}
procedure TZTimer.Start;
{$IFDEF WIN32}
begin
QueryPerformanceCounter(FStart);
end;
{$ENDIF}
{$IFDEF WIN64}
asm
.NOFRAME
sub rsp, 8
lea rcx, self.FStart
mov [rsp], rcx
call QueryPerformanceCounter
add rsp, 8
end;
{$ENDIF}
procedure TZTimer.Stop;
{$IFDEF WIN32}
begin
QueryPerformanceCounter(FEnd);
end;
{$ENDIF}
{$IFDEF WIN64}
asm
.NOFRAME
sub rsp, 8
lea rcx, self.FEnd
mov [rsp], rcx
call QueryPerformanceCounter
add rsp, 8
end;
{$ENDIF}
function TZTimer.TimeInSec: Double;
{$IFDEF WIN32}
begin
Result := (FEnd - FStart) * FSEC;
end;
{$ENDIF}
{$IFDEF WIN64}
asm
.NOFRAME
mov rax, self.FEnd
sub rax, self.FStart
cvtsi2sd xmm0, rax
mulsd xmm0, double ptr [self.FSEC]
end;
{$ENDIF}
function TZTimer.TimeInMSec: Double;
{$IFDEF WIN32}
begin
Result := (FEnd - FStart) * FMSEC;
end;
{$ENDIF}
{$IFDEF WIN64}
asm
.NOFRAME
mov rax, self.FEnd
sub rax, self.FStart
cvtsi2sd xmm0, rax
mulsd xmm0, double ptr [self.FMSEC]
end;
{$ENDIF}
procedure TZTimer.Reset;
asm
.NOFRAME
xor rax, rax
mov self.FStart, rax
mov self.FEnd, rax
mov self.FSEC, rax
mov self.FMSEC, rax
end;
initialization
AuxTimer.Init;
FpsTimer.Init;
SortTimer.Init;
end.