mmruzek wrote:
I ran the Sieve benchmark (previously discussed in this thread) and calculation of prime numbers up to 1000 takes 19 seconds. I'm pretty happy with that, considering I'm at 1MHZ and running a self-written interpreted language. I'm considering increasing the number of keyboard stacks from 16 to 256. I've been spending alot of time reading about BCPL and C Compilers. Not ready to take the leap yet!
Michael
19 seconds isn't bad, but I wonder if you're missing the "trick" of only checking up to the square root of the number of numbers? (31 in this case)
(Although I'm now wondering if you meant generate the first 1000 primes? If I change my code to do that the time does up to 882ms with 10,000 locations in the sieve)
This is my implementation of the old Byte Sieve program in BCPL - it includes an integer square root function and runs in just 84 milliseconds.
Below is the output of the source code, a compile and run on my Ruby 816 board - it's a 16Mhz 65C816 8/16 bit CPU running a bytecode interpreter for the BCPL compiled bytecode (CINTCODE). It runs at maximum of 400K instructions/second and usually much much slower. It's a 32-bit VM and spends a lot of its time overcoming the 64K banks of RAM that the '816 manages.
As for actually writing the compiler - I didn't do that - I just provided the run-time and bytecode interpreter/vm for it all. While I've written many interpreters I've yet to tackle a "proper" compiler for anything - maybe one day!
Still - designing your own CPU and computer from scratch, writing your own language for it is still very impressive. Well done.
-Gordon
Code:
% cat byteSieve.b
// Byte Sieve - Integer version
GET "libhdr.h"
GET "sys.h"
MANIFEST
{
size = 1000
}
LET start () = VALOF
{
LET flags = getvec (size/4 + 1)
LET tStart, tEnd = ?,?
LET count = 0
writes ("Starting*n")
UNLESS flags THEN
{
writes ("Out of memory*n")
RESULTIS 1
}
FOR i = 0 TO size DO // Assume everything is prime to start with
flags%i := 1
flags%0 := 0 // 0 and 1 are not prime
flags%1 := 0
tStart := sys (Sys_cputime)
FOR i = 2 TO sqrt (size) DO
{
LET k = ?
IF flags%i = 1 THEN // It's prime
{
LET k = i + i
WHILE k <= size DO
{
flags%k := 0 // ... but all multiples aren't
k := k + i
}
}
}
tEnd := sys (Sys_cputime)
writef ("Time: %d ms*n", tEnd - tStart)
FOR i = 0 TO size-1 DO
TEST flags%i THEN
wrch ('**')
ELSE
wrch ('.')
newline ()
// Count
FOR i = 0 TO size DO
IF flags%i = 1 THEN
count := count + 1
writef (" %d primes found.*n", count)
freevec (flags)
RESULTIS 0
}
AND sqrt (s) = VALOF
{
LET x,y = s/2, (s/x+x)/2
writef ("sqrt (%n) = ", s)
{
x := y
y := (s/x+x)/2
} REPEATWHILE x > y
writef ("%n*n", x)
RESULTIS x
}
%
% bc byteSieve.b to byteSieve
Ruby BCPL (10 Oct 2014) with simple floating point
Code size = 356 bytes of 32-bit little ender Cintcode
%
% byteSieve
Starting
sqrt (1000) = 31
Time: 84ms
168 primes found.
%