[Back to TIMING SWAG index] [Back to Main SWAG index] [Original]
{$G+,S-,R-,Q-}
program timer;
{ Program to time short segments of code; inspired by Michael Abrash's
Zen timer. Donated to the public domain by D.J. Murdoch }
uses
opdos; { Object Professional unit, needed only for TimeMS,
a millisecond timer. }
const
onetick = 1/33E6; { This is the time in seconds for one cpu cycle.
I've got it set for a 33 Mhz machine. }
{ Instructions: put your code fragment into a short routine called Segment.
It should leave the stack unchanged, or it'll blow up when we clone it.
It *must* have a far return at the end. Play around with declaring it
as an assembler procedure or not to see the cost of the TP entry and
exit code. }
{ This example is Sean Palmer's "var2 := var1 div 2" replacement fragment. }
var
var1,var2 : integer;
procedure Segment; far; assembler;
asm
mov ax,var1
sar ax,1
jns @S
adc ax,0
@S:
mov var2,ax
end;
{ This is the comparison TP code. Note that it includes entry/exit code;
play around with variations on the assembler version to make it a fair
comparison }
(*
procedure Segment; far;
begin
var2 := var1 div 2;
end;
*)
{ This procedure is essential!!! Do not move it. It must follow
Segment directly. }
procedure Stop;
begin
end;
{ This routine will only be called once at the beginning of the program;
set up any variables that Segment needs }
procedure Setup;
begin
var1 := 5;
writeln('This run, var1=',var1);
end;
const
maxsize=65520;
RETF = $CB;
var
p : pointer;
src,dest : ^byte;
size : word;
repeats : word;
i : word;
start,finish : longint;
count : longint;
main,overhead,millisecs : real;
begin
setup;
{ Get a segment of memory, and fill it up with as many copies
of the segment as possible }
size := ofs(stop) - ofs(Segment) -1;
repeats := maxsize div size;
getmem(p, size*repeats + 1);
src := @Segment;
dest := p;
for i:=1 to repeats do
begin
move(src^,dest^,size);
inc(dest,size);
end;
{ Add a final RETF at the end. }
dest^ := RETF;
{ Now do the timing. Keep repeating one second loops indefinitely. }
writeln(' Bytes Clocks ns MIPS');
repeat
{ First loop: one second worth of calls to the segment }
start := timems;
count := 0;
repeat
asm
call dword ptr p
end;
finish := timems;
inc(count);
until finish > 1000+start;
main := (finish - start)/repeats/count;
{ Second loop: 1/2 second worth of calls to the RETF }
start := timems;
count := 0;
repeat
asm
call dword ptr dest
end;
finish := timems;
inc(count);
until finish > 500+start;
overhead := (finish-start)/count;
millisecs := (main-overhead/repeats);
writeln(size:6,millisecs/1000/onetick:11:1,
1.e6*millisecs:11:0,
1/millisecs/1000:11:3);
until false;
end.
--- Msg V3.2
* Origin: Murdoch's Point, Kingston, Ont, Canada - - (1:249/99.5)
[Back to TIMING SWAG index] [Back to Main SWAG index] [Original]