Browse Source

* New LEA bench test

J. Gareth "Curious Kit" Moreton 1 year ago
parent
commit
a353d7c65b
1 changed files with 96 additions and 0 deletions
  1. 96 0
      tests/bench/blea.pp

+ 96 - 0
tests/bench/blea.pp

@@ -0,0 +1,96 @@
+{ %CPU=i386,x86_64 }
+program blea;
+
+{$IF not defined(CPUX86) and not defined(CPUX86_64)}
+  {$FATAL This test program requires an Intel x86 or x64 processor }
+{$ENDIF}
+
+{$MODE OBJFPC}
+{$ASMMODE Intel}
+
+uses
+  SysUtils;
+  
+type
+  TBenchmarkProc = function(const Input, X, Y: LongWord): LongWord;
+ 
+
+function Checksum_PAS(const Input, X, Y: LongWord): LongWord;
+var
+  Counter: LongWord;
+begin
+  Result := Input;
+  Counter := Y;
+  while (Counter > 0) do
+    begin
+      Result := Result + X + $87654321;
+      Result := Result xor Counter;
+      Dec(Counter);
+    end;
+end;
+
+function Checksum_ADD(const Input, X, Y: LongWord): LongWord; assembler; nostackframe;
+asm
+@Loop1:
+  ADD Input, $87654321
+  ADD Input, X
+  XOR Input, Y
+  DEC Y
+  JNZ @Loop1
+  MOV Result, Input
+end;
+
+function Checksum_LEA(const Input, X, Y: LongWord): LongWord; assembler; nostackframe;
+asm
+@Loop2:
+  LEA Input, [Input + X - 2023406815] {+$87654321 in decimal}
+  XOR Input, Y
+  DEC Y
+  JNZ @Loop2
+  MOV Result, Input
+end;
+
+function Benchmark(const name: string; proc: TBenchmarkProc; Z, X: LongWord): LongWord;
+const
+  internal_reps = 1000;
+var
+  start: TDateTime;
+  time: double;
+  reps: cardinal;
+begin
+  Result := Z;
+  reps := 0;
+  Write(name, ': ');
+  start := Now;
+  repeat
+    inc(reps);
+    Result := proc(Result, X, internal_reps);
+  until (reps >= 100000);
+  time := ((((Now - start) * SecsPerDay) * 1e9) / internal_reps) / reps;
+  WriteLn(time:0:(2 * ord(time < 10)), ' ns/call');
+end;
+
+var
+  Results: array[0..2] of LongWord;
+  FailureCode: Integer;
+begin
+  Results[0] := Benchmark('   Pascal control case', @Checksum_PAS, 5000000, 1000);
+  Results[1] := Benchmark(' Using LEA instruction', @Checksum_LEA, 5000000, 1000);
+  Results[2] := Benchmark('Using ADD instructions', @Checksum_ADD, 5000000, 1000);
+  
+  FailureCode := 0;
+
+  if (Results[0] <> Results[1]) then
+    begin
+      WriteLn('ERROR: Checksum_LEA doesn''t match control case');
+      FailureCode := FailureCode or 1;
+    end;
+  if (Results[0] <> Results[2]) then
+    begin
+      WriteLn('ERROR: Checksum_ADD doesn''t match control case');
+      FailureCode := FailureCode or 2
+    end;
+    
+  if FailureCode <> 0 then
+    Halt(FailureCode);
+end.