Iterointi luuppi vaikka Mandelbrotin joukon laskemiseen. Koodi on optimoitu nopeimpaan kuosiin, vai onko sinulla ideaa, miten luuppiin saisi enemmän tehoa?
/* Jouni Aro 22.2.2000 */ #ifndef __LONG_DOUBLE #define __LONG_DOUBLE typedef long double lreal; #define lr(ex) (lreal)(ex) #endif #define MAX_ITER 256 int iteroi(lreal a, lreal b) { int loop=0; lreal rr=lr(0); lreal x=0, y=0, r, i; while (rr < lr(4096)) { r=x*x; i=y*y; rr=r+i; y=2*x*y+b; x=r-i+a; if (++loop==MAX_ITER) return 0; } return loop; }
Tuossapa on yksinkertainen main-funktio, joka piirtää Mandelbrotin joukon. Kaikki ylimääräinen Windows-paska on ohjelmoitu omaan yksikköön...
/* Jouni Aro 3.1.2025 */ #pragma hdrstop #include <windows.h> #include "exwin.cpp" #include "skaala.cpp" #define MAX_ITER 256 int iteroi(lreal a, lreal b) { int loop=0; lreal rr=lr(0); lreal x=0, y=0, r, i; while (rr < lr(4096)) { r=x*x; i=y*y; rr=r+i; y=2*x*y+b; x=r-i+a; if (++loop==MAX_ITER) return 0; } return loop; } int OwnMain(void) { skaala S; S.set(0, 0, 1024, 1024); // piirto-ikkunan koko S.set(lr(-2), lr(0.8), lr(-1.4), lr(1.4)); // ikkunan skaala for (int x=0; x<1024; x++) for (int y=0; y<1024; y++) { lreal a=S.getxl(x); lreal b=S.getyl(y); int c=iteroi(a, b); putpixel(x, y, RGB(c, c, c)); } waitForEsc(); return 0; }
section .data MAX_ITER equ 256 width equ 1024 height equ 1024 section .bss loop resd 1 rr resq 1 x resq 1 y resq 1 r resq 1 i resq 1 a resq 1 b resq 1 c resd 1 section .text global _start _start: ; Initialize variables mov dword [loop], 0 fldz fst qword [rr] fldz fst qword [x] fldz fst qword [y] iterate: ; while (rr < 4096) fld qword [rr] fld qword [4096.0] fcomi st0, st1 jae .end_loop ; r = x * x fld qword [x] fmul st0, st0 fst qword [r] ; i = y * y fld qword [y] fmul st0, st0 fst qword [i] ; rr = r + i fld qword [r] fadd qword [i] fst qword [rr] ; y = 2 * x * y + b fld qword [x] fmul qword [y] fadd qword [y] fadd qword [b] fst qword [y] ; x = r - i + a fld qword [r] fsub qword [i] fadd qword [a] fst qword [x] ; if (++loop == MAX_ITER) return 0 inc dword [loop]
Ei yhtään ylimääräistä koodia. Hienosti ohjelmoitu!
Miksi kirjoittaa assemblyä samalla tavalla kuin korkeamman tason ohjelmointikielen kääntäjä olisi ehkä joskus 60-luvulla koodia tuottanut? Nopealla silmäyksellä ohjelmalistaus ei ole edes kokonainen.
jalski@
Menit vähintään vain parillakymmenellä vuodella metsään tuon 60-lukusi kanssa. MASM ei ole häipynyt yhtään mihinkään vaikkei Microsoft ole myynyt sitä enää aikoihin erillisenä pakettina. Se sisältyy kuitenkin lähes jokaiseen em. puljun julkaisemaan SDK:n ja C-kääntäjään ja toimitetaan mm. Visual Studio paketin mukana. Nyt on niin, että tuo vääntö toimii yhtä hyvin 32 kuin 64 bittisessä ympäristössä millä tahansa alustalla jolla on ylipäätään jotain merkitystä. Kun nyt lässyttelit listauksista niin käypä kurkkaamassa nimimerkki jone2712 avausulostuloa aiheesta, eli mitä hän kysyi...
Meinasin vaan, että miksi jos haluaa kirjoittaa assemblyä tekee sen kuin vanha korkeamman tason ohjelmointikielen kääntäjä mikä ei osaa käyttää rekistereitä edes silmukkalaskureina.
Missä koodissa on näkyvillä '.end_loop' label tai miten 'inc dword [loop]' palauttaa nollan mikäli laskuri on suurempi kuin 'MAX_ITER'?
Mandelbrot laskennassa assemblyä suurempi optimointi olisi rinnakkaisuus laskentaan ja mikäli kuva olisi symmetrinen voisi laskea vaan puolet kuvasta ja piirtää molemmat puolet.
Ihme kitinää... Just don't lose your sense of humour while you're coding (if you've even ever had one)
😉
Lisää tehoa saa kun laittaa sen pyörimään näytönohjaimelle. Se on nykyään sillein.