Jump to content
IGNORED

Mad Pascal


Recommended Posts

Ok, I figured it out. I went through Mad Pascal examples code which uses memory address above $a000. Of course, programs work well and you can use this area freely, but BASIC must be switched off manually for proper operation. I am talking about code read from resource files at program startup (images, text, music...). If you leave BASIC on (not pressing Option when starting real machine or emulator), garbage appears on the screen (collading with previous data on $a000 area). We know all of that, but anyway... The example is PacMad, you can try it and you will know what I am talking about.

 

I can provide additional code in my program to automatically turn BASIC off and I can use this area freely, but the problem with reading resource files will remain.

 

The whole point is that it is not that easy to do that on the first glance in high language (not assembler). It is easy to say "The program must take care of automatically switching BASIC off!". In practice things can become more complicated than that. Most other machines didn't have to cope with this problem at all.

 

Link to comment
Share on other sites

On 12/20/2015 at 10:53 PM, ilmenit said:

I have fixed the C code to be less Pascal-like (using unsinged char for boolean, memset for fillchar, register for indexes etc.).

 

With an older version of cc65 (2.13.3) and optimizations turned on:

cl65 -l -o sieve.c.xex -t atari -Osir -Cl --add-source sieve.c

 

I receive:

C - 608 ticks vs Mads Pascal - 1474 ticks

For 0...255 to compare with Action! it's 14 ticks.

 

The code, xex and asm output attached.

sieve-c.zip 6.18 kB · 242 downloads

C - 608 ticks (optimizations turned on)

C - 856 ticks (optimizations turned off)

Mad Pascal - 670 ticks (variables on ZEROPAGE, $DEFINE FAST)

Mad Pascal - 752 ticks (standard)

 

bench_sieve.zip

Edited by tebe
  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Here are my tests on atari800 PAL :] Sources mostly included ;)

Programming languages in the latest official version for February 20, 2020.

CC65           YoshPlus:   41844 iterations in 100 ticks
Mad Pascal     YoshPlus:   35572 iterations in 100 ticks
Action!        YoshPlus:   33239 iterations in 100 ticks
Quick 2.2      YoshPlus:   21320 iterations in 100 ticks
Quick 1.6      YoshPlus:   16242 iterations in 100 ticks
PL65           YoshPlus:    4708 iterations in 100 ticks
FastBasic FBI  YoshPlus:    2427 iterations in 100 ticks
fig-Forth 1.1  YoshPlus:     715 iterations in 100 ticks
CLSN Pascal    YoshPlus:     487 iterations in 100 ticks

CC65            Chessboard:   76 iterations in 150 ticks
Mad Pascal      Chessboard:   40 iterations in 150 ticks
Action!         Chessboard:   35 iterations in 150 ticks
Quick 2.2       Chessboard:   27 iterations in 150 ticks
Quick 1.6       Chessboard:   16 iterations in 150 ticks
PL65            Chessboard:   12 iterations in 150 ticks

MADS (opt)         SIEVE:    440 ticks in 10 iterations
CC65 (opt)         SIEVE:    602 ticks in 10 iterations
Mad Pascal (opt)   SIEVE:    644 ticks in 10 iterations
Mad Pascal         SIEVE:    739 ticks in 10 iterations
Action!            SIEVE:   1003 ticks in 10 iterations
Advan BASIC (opt)  SIEVE:   1050 ticks in 10 iterations
Quick 1.6          SIEVE:   2022 ticks in 10 iterations
Quick 2.2          SIEVE:   2199 ticks in 10 iterations
PL65               SIEVE:   3853 ticks in 10 iterations
FastBasic FBI      SIEVE:   6312 ticks in 10 iterations
Advan BASIC        SIEVE:   6800 ticks in 10 iterations
fig-Forth 1.1      SIEVE:   8482 ticks in 10 iterations
Turbo-BASIC XL [C] SIEVE:  16880 ticks in 10 iterations
Turbo-BASIC XL     SIEVE:  46060 ticks in 10 iterations
BASIC              SIEVE: 133960 ticks in 10 iterations

 

A8 SIEVE Benchmark.png

 

 

A8-Benchmarks.zip

Edited by zbyti
correct package
  • Like 3
Link to comment
Share on other sites

Proper (REAL) SIEVE Benchmark

// Eratosthenes Sieve Benchmark

uses crt;

{$define FAST}

const
 size = 8191;
 sqr_count = 91;

var
  flags: array [0..size] of boolean;
  rtClock: byte absolute $14;

{$ifdef FAST}
  n: word absolute $e0;
  k: word absolute $e2;
  count: word absolute $e6;
{$else}
  n, k, count: word;
{$endif}

begin
    writeln('Mad Pascal');
    writeln('Eratosthenes Sieve Benchmark');
    
    rtClock := 0;
    fillchar(flags, sizeof(flags), true);
    for n := 2 to sqr_count do begin
        if flags[n] then begin
            k := n shl 1;
            while k <= size do begin
                flags[k] := false;
                Inc(k,n);
            end;
        end;    
    end;
    writeln(rtClock, ' ticks');
    
    count :=0;
    for n := 2 to size do begin
        if flags[n] then Inc(count);
    end;

    writeln(count, ' primes');
    repeat until keypressed;
end.
RTCLOCK@20:byte

const SQRT_COUNT = 91

top:0..8191
sieve:array(top) of 0..1
k,j,prime:top
start,time:byte

"Atalan computing primes..."

for k 
	sieve(k) = 1

RTCLOCK = 0

for i:2..SQRT_COUNT where sieve(i) = 1
		j = i * 2
		while j<=8191
			sieve(j) = 0
			j = j + i

time = RTCLOCK
 
"Time used: [time] ticks"
"Press Q to quit, any other key for list"

CH = none
until CH <> none

for k where sieve(k) = 1 until CH = Q
	 "[k]"
	
CH = none

real-basic-sieve.png

A8 SIEVE Benchmark.png

Edited by zbyti
add Atalan proper sieve code
Link to comment
Share on other sites

Hi!

33 minutes ago, zbyti said:

 

Proper SIEVE Benchmark

 


// Eratosthenes Sieve Benchmark

uses crt;

{$define FAST}

const
 size = 8191;
 sqr_count = 91;

var
  flags: array [0..size] of boolean;
  rtClock: byte absolute $14;

{$ifdef FAST}
  n: word absolute $e0;
  k: word absolute $e2;
  count: word absolute $e6;
{$else}
  n, k, count: word;
{$endif}

begin
    writeln('Mad Pascal');
    writeln('Eratosthenes Sieve Benchmark');
    
    rtClock := 0;
    fillchar(flags, sizeof(flags), true);
    for n := 2 to sqr_count do begin

Here you changed the code, using "sqr_count" as the upper limit instead of the full size is misleading, as all other programs do the complete loop.

 

So, you results sadly are not comparable.

 

Have Fun!

Link to comment
Share on other sites

@dmsc

https://rosettacode.org/wiki/Sieve_of_Eratosthenes look at this implementations and compare with proper result https://jalu.ch/coding/primes/list.php

Fake SIEVE contains even numbers as result but sadly it's popular benchmark on Internet.

atari00121.png

All FAKE SIEVE in my test implements the same algorithm, they all are comparable. I simply start implement proper algorithm and I start call it REAL.

Edited by zbyti
add info
Link to comment
Share on other sites

FAKE SIEVE

// Fake Eratosthenes Sieve Benchmark

uses crt, sysutils;

{$define FAST}

const
 size = 8191;

var
  flags: array [0..size] of boolean;

  iter: byte;
  starttime: cardinal;

{$ifdef FAST}
  i: word absolute $e0;
  k: word absolute $e2;
  prime: word absolute $e4;
  count: word absolute $e6;
{$else}
  i, k, prime, count: word;
{$endif}

begin
    starttime := GetTickCount;
    fillchar(flags, sizeof(flags), true);

    i:=0; count := 0;

    while i <= size do begin

        if flags[i] then begin

            prime := i shl 1 + 3;
            k := prime + i;

            while (k <= size) do begin
                flags[k] := false;
                inc(k, prime);
            end;
            inc(count);
        end;

    inc(i);
    end;

    writeln(count, ' primes');
    writeln(GetTickCount - starttime, ' ticks');
 
    count := 0;
     for i := 3 to size do begin
        if flags[i] then begin
            if (i mod 2) = 0 then begin inc(count) end;
        end;
    end;
    writeln(count, ' even numbers');

   readkey;
end.

 

atari000.png

Edited by zbyti
Link to comment
Share on other sites

On 2/25/2020 at 11:17 AM, zbyti said:

Here are my tests on atari800 PAL :] Sources mostly included ;)

Programming languages in the latest official version for February 20, 2020.


CC65           YoshPlus:   41844 iterations in 100 ticks
Mad Pascal     YoshPlus:   35572 iterations in 100 ticks
Action!        YoshPlus:   33239 iterations in 100 ticks
Quick 2.2      YoshPlus:   21320 iterations in 100 ticks
Quick 1.6      YoshPlus:   16242 iterations in 100 ticks
PL65           YoshPlus:    4708 iterations in 100 ticks
FastBasic FBI  YoshPlus:    2427 iterations in 100 ticks
fig-Forth 1.1  YoshPlus:     715 iterations in 100 ticks
CLSN Pascal    YoshPlus:     487 iterations in 100 ticks

CC65            Chessboard:   76 iterations in 150 ticks
Mad Pascal      Chessboard:   40 iterations in 150 ticks
Action!         Chessboard:   35 iterations in 150 ticks
Quick 2.2       Chessboard:   27 iterations in 150 ticks
Quick 1.6       Chessboard:   16 iterations in 150 ticks
PL65            Chessboard:   12 iterations in 150 ticks

MADS (opt)         SIEVE:    440 ticks in 10 iterations
CC65 (opt)         SIEVE:    602 ticks in 10 iterations
Mad Pascal (opt)   SIEVE:    644 ticks in 10 iterations
Mad Pascal         SIEVE:    739 ticks in 10 iterations
Action!            SIEVE:   1003 ticks in 10 iterations
Advan BASIC (opt)  SIEVE:   1050 ticks in 10 iterations
Quick 1.6          SIEVE:   2022 ticks in 10 iterations
Quick 2.2          SIEVE:   2199 ticks in 10 iterations
PL65               SIEVE:   3853 ticks in 10 iterations
FastBasic FBI      SIEVE:   6312 ticks in 10 iterations
Advan BASIC        SIEVE:   6800 ticks in 10 iterations
fig-Forth 1.1      SIEVE:   8482 ticks in 10 iterations
Turbo-BASIC XL [C] SIEVE:  16880 ticks in 10 iterations
Turbo-BASIC XL     SIEVE:  46060 ticks in 10 iterations
BASIC              SIEVE: 133960 ticks in 10 iterations

 

A8 SIEVE Benchmark.png

A8-Banchmarks.zip 90.68 kB · 3 downloads

Basic++: 1899 prime in 7849 jiffies. This is faster than I thought. It is not ideal in Turbobasic since this still does a line search, although abbreviated, for each for-loop. Basic++ pushes the address to the stack.

  • Like 1
Link to comment
Share on other sites

2 minutes ago, thorfdbg said:

Basic++: 1899 prime in 7849 jiffies. This is faster than I thought. It is not ideal in Turbobasic since this still does a line search, although abbreviated, for each for-loop. Basic++ pushes the address to the stack.

With "cheating", i.e. math pack patch as in "host does the computation", down to 5291 jiffies. Of course, that is then not a fair benchmark, but it given an impression of where the overhead of the basic interpreter is.

Link to comment
Share on other sites

3 minutes ago, zbyti said:

Basic++ REAL Sieve :]

How can I speed it up? Does this have a compiler?

 

You better use it with Os++ because the Os++ math pack is also considerably faster. As far as a compiler is concerned - well, any Atari Basic compiler would do. I would suggest to try it with the ABC compiler, which should create a suitable fast binary.

 

 

Link to comment
Share on other sites

9 minutes ago, thorfdbg said:

You better use it with Os++ because the Os++ math pack is also considerably faster. As far as a compiler is concerned - well, any Atari Basic compiler would do. I would suggest to try it with the ABC compiler, which should create a suitable fast binary.

Result for the ABC compiled code: 1899 primes in 2009 jiffies.

 

Link to comment
Share on other sites

 

@drac030 THX :]

Real Sieve Native FastBasic 4.0 FBI

? "STARTING FASTBASIC..."
STIME = TIME
DIM FLAGS(8190) BYTE
MSET ADR(FLAGS), 8190,0
FOR N=2 TO 91
 IF NOT FLAGS(N)
  FOR K=N*N TO 8190 STEP N
   FLAGS(K)=1
  NEXT K
 ENDIF
NEXT N
ETIME = TIME
? "JIFFIES: ";ETIME-STIME
COUNT=0
FOR N=2 TO 8191
 IF NOT FLAGS(N)
  COUNT=COUNT+1
 ENDIF
NEXT N
? "PRIMES: ";COUNT

gets: 335 ticks

./fastbasic-int RESIEVE.FBI fbisieve.asm
cl65 -t atari -C fastbasic.cfg fbisieve.asm -o fbisieve.xex fastbasic-fp.lib

gets: 314 ticks

 

atari002.png

Screenshot_2020-02-27_10-55-02.png

Edited by zbyti
typo
  • Like 1
Link to comment
Share on other sites

6 hours ago, zbyti said:

 

@drac030 THX :]

Real Sieve Native FastBasic 4.0 FBI


? "STARTING FASTBASIC..."
STIME = TIME
DIM FLAGS(8190) BYTE
MSET ADR(FLAGS), 8190,0
FOR N=2 TO 91
 IF NOT FLAGS(N)
  FOR K=N*N TO 8190 STEP N
   FLAGS(K)=1
  NEXT K
 ENDIF
NEXT N
ETIME = TIME
? "JIFFIES: ";ETIME-STIME
COUNT=0
FOR N=2 TO 8191
 IF NOT FLAGS(N)
  COUNT=COUNT+1
 ENDIF
NEXT N
? "PRIMES: ";COUNT

gets: 335 ticks


./fastbasic-int RESIEVE.FBI fbisieve.asm
cl65 -t atari -C fastbasic.cfg fbisieve.asm -o fbisieve.xex fastbasic-fp.lib

gets: 314 ticks

 

atari002.png

Screenshot_2020-02-27_10-55-02.png

Basic++, with Os++ gives me 3874 jiffies, 1028 primes. You are likely using the original Os, with the original (slow) mathpack.

 

 

Link to comment
Share on other sites

Millfork              YoshPlus: 41921 iterations in 100 ticks
CC65                  YoshPlus: 41844 iterations in 100 ticks
Mad Pascal            YoshPlus: 35572 iterations in 100 ticks
Action!               YoshPlus: 33239 iterations in 100 ticks
Quick 2.2             YoshPlus: 21320 iterations in 100 ticks
Quick 1.6             YoshPlus: 16242 iterations in 100 ticks
PL65                  YoshPlus:  4708 iterations in 100 ticks
FastBasic FBI         YoshPlus:  2427 iterations in 100 ticks
fig-Forth 1.1         YoshPlus:   715 iterations in 100 ticks
CLSN Pascal           YoshPlus:   487 iterations in 100 ticks

Millfork            Chessboard:    79 iterations in 150 ticks
CC65                Chessboard:    76 iterations in 150 ticks
Mad Pascal          Chessboard:    40 iterations in 150 ticks
Action!             Chessboard:    35 iterations in 150 ticks
Quick 2.2           Chessboard:    27 iterations in 150 ticks
Quick 1.6           Chessboard:    16 iterations in 150 ticks
PL65                Chessboard:    12 iterations in 150 ticks

 

Screenshot_2020-02-27_18-30-01.png

A8 SIEVE Benchmark.ods

Link to comment
Share on other sites

With @xxl tips, Atari BASIC counts faster.

@xxl claims that he can implement the same algorithm even faster but I have no idea how he does it :)

 

You can omit even numbers but then it won't be the same benchmark any more.


10 POKE 20,0:POKE 19,0:COUNT=0
20 DIM F$(8192):F$="F":F$(8192)=F$:F$(2)=F$:X=ADR(F$)
30 FOR N=2 TO 91
40 IF PEEK(N+X)=1 THEN 80
50 FOR K=N*N TO 8190 STEP N:POKE K+X,1
70 NEXT K
80 NEXT N
90 TIME=PEEK(20)+256*PEEK(19)
100 ? TIME;" TICKS"
200 FOR N=2 TO 8191
210 IF PEEK(N+X)=70 THEN COUNT=COUNT+1
220 NEXT N
230 ? COUNT;" PRIMES"

 

atari001.png

Edited by zbyti
omit even numbers info
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...