lunedì 11 novembre 2019

Mandelbrot in 67 secondi su C64

Riuscire a calcolare l'insieme di Mandelbrot su un C64 e' stata una dellle sfide (perse) di quando ero ragazzo e leggevo Dewdney su Le Scienze


Adesso dopo tanti anni sono arrivato a 67 secondi  e sotto al minuto usando ottimizzazioni un po' piu' spinta (si perde pero' la cuspide del cardioide). Ulteriori miglioramenti possono essere fatti abbassando il limite massimo della variable k e usando una lookup table dei quadrati gia' calcolata

Per il calsolo sono stati utilizzati i seguenti sistemi

1) Emulazione Vice 3.3 al 100% di velocita' per emulare un C64 reale
2) Uso della tabella di lookup dei quadrati
3) Matematica a numeri interi
4) Algoritmo di calcolo che non prevede moltiplicazioni ma solo somme e sottrazioni
5) Uso di eseguibile compilato con CC65
6) Uso della simmetria


Massima ottimizzaziona impiegata con perdita della cuspide del cardioide
L'algoritmo e' quello gia' visto qui . Ottimizzazione del controllo sul cardiode da Wikipedia


da compilare con

cl65 -O -o "mande.prg" - t c64 --static-locals fractint.c

in giallo l'ottimizzazione del controllo sul cardioide

per migliorare gli algoritmi si puo' fare riferimento al seguente link

===========fractint.c===============
#include <stdio.h>
#include <stdlib.h>
#include <cc65.h>
#include <conio.h>
#include <tgi.h>


static void Mand (void)
{

    static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_ORANGE };
    register unsigned s,k;
    register int zi,zr,jr,ji,a,test;
    int q[180];

    tgi_setpalette (Palette);
    tgi_setcolor (1);

    for (s=1; s<170;s++)
{
q[s] = (int) (s*s/32);
}

    for (jr=-63;jr<18;jr++)
{
for (ji=-63; ji<1;ji++)
{
zi = zr = 0;

test = q[abs(jr-8)] + q[abs(ji)];
if (test*(test+(jr-8)) >  (q[abs(ji)]/4))

{
for (k=0; k<=25;k++)
{
a = q[abs(zr)] - q[abs(zi)] + jr;
zi = q[abs(zr)]+q[abs(zi)]-q[abs(zr-zi)]+ji;
zr = a;
if (q[abs(zr)] + q[abs(zi)] >  128 )
{
tgi_setcolor(k%2);
tgi_setpixel(jr+64,ji+64);
tgi_setpixel(jr+64,128-abs(63+ji));
k=26;
}
}
}
}
}

    cgetc ();
    tgi_clear ();
}



int main (void)
{

    tgi_load_driver (tgi_stddrv);
    tgi_init ();
    tgi_clear ();

    Mand();

    tgi_unload ();
    return EXIT_SUCCESS;
}

Nessun commento:

Posta un commento

Dockerizza Flask

Un esempio semplice per inserire in un container Docker una applicazione Flask Partiamo da una semplice applicazione che ha un file app.py ...