Benchmark Implementation

Main Page

To prove I have a sense of humour, SieveAhl is written in Modula-2. Yes, that *is* pretty funny, isn't it?

Common Definitions

VAR
	ticks: LONGINT;

PROCEDURE TickCount(): LONGINT; CODE 0A975H;
PROCEDURE Random(): INTEGER; CODE 0A861H;

PROCEDURE BoundedTicks(tick1, tick2: LONGINT);
(* needed because of some weirdness with tick2 < tick1! *)
BEGIN;
	IF (tick1 < tick2) THEN
		ticks := tick2 - tick1;
	ELSE
		ticks := tick1 - tick2;
	END;
END BoundedTicks;

Ahl's Simple Benchmark

The original BASIC version of Ahl's Simple Benchmark is below. Originally the benchmark was designed for testing the relative accuracies and random number generators of various microcomputer BASICs (this version below will run on most interpreters and compilers, including the Commodore 64 and Apple II series). We are only interested in runtime, so these values are calculated and then thrown away. Because the Mac Toolbox routine used for pseudo-random numbers generates integers (BASIC rnd() generates floating point), the variable r was made integer too, not real. [Strictly speaking, it could overflow, not being longint, but audaciously I assumed that the net sum of all numbers returned by the Toolbox random number generator would be zero and in practise this seems to be true.]
PROCEDURE DoAhlsBenchMark(iterations: LONGINT): INTEGER;
(*
	10 rem Ahl's simple benchmark
	20 for n = 1 to 100: a = n
	30 for i = 1 to 10
	40 a = sqr(a): r = r + rnd(1)
	50 next i
	60 for i = 1 to 10
	70 a = a^2: r = r + rnd(1)
	80 next i
	90 s = s + a: next n
	100 print "Accuracy ";abs (1010-s/5)
	110 print "Random ";abs (1000-r)
*)

VAR
	i, r: INTEGER;
	a: REAL;
	s: LONGREAL;
	n, firsttick: LONGINT;
	lasttick: LONGINT;
BEGIN;
	
	firsttick := TickCount();
	n:=0D; (* FOR ... *)
	REPEAT;
		a:= FLOAT(n);
		FOR i:=1 TO 10 DO
			a:=Sqrt(a);
			r:=r+Random();
		END;
		FOR i:=1 TO 10 DO
			a:=a*a;
			r:=r+Random();
		END;
		s:=s+LONG(a);
	INC(n);
	UNTIL n = iterations;
	lasttick := TickCount();
	BoundedTicks(firsttick, lasttick);
	RETURN 0;
END DoAhlsBenchMark;

Sieve of Eratosthenes

The Sieve is a well-known prime generation algorithm. This version is based on BYTE Magazine's implementation (here is C source), which iterates over an interval (classically 0-8190 for most benchmarks based on it including this one) and, based on a starting prime (here, 3), marks all multiples of that prime as non-prime and advances by index+index+3 (first 3, then 5, then 7 ...), counting all primes it finds. 2 is not iterated over as all of the other prime iterations will catch it.

The number of primes in this interval is 1,899 and this is returned as a "checksum" to verify operation. The Sieve of Eratosthenes is a pure integer benchmark.

PROCEDURE DoSieveBenchMark(iterations: LONGINT): INTEGER;
VAR
	iter, firsttick, lasttick: LONGINT;
	count, i, k, prime: INTEGER;
	flags: ARRAY[0..8190] OF BOOLEAN;
BEGIN;
	firsttick := TickCount();
	iter := 0D; (* FOR ... *)
	REPEAT;
		count := 0;
		FOR i:=0 TO 8190 DO;
			flags[i] := TRUE;
		END;
		FOR i:=0 TO 8190 DO;
			IF (flags[i]) THEN
				prime := i+i+3;
				k:=i+prime;
				WHILE (k <= 8190) DO
					flags[k] := FALSE;
					k := k+prime;
				END;
				count := count + 1;
			END;
		END;
	INC(iter);
	UNTIL iter = iterations;
	lasttick := TickCount();
	BoundedTicks(firsttick, lasttick);
	RETURN count;
END DoSieveBenchMark;

Cameron Kaiser