Se zájmem jsem si v Mikrobázi 6/88 přečetl článek nostalgie, podepsaný značkou -elzet-. Posílám vám výpisy dvou programů – jeden pro ZX Spectrum, druhý pro IBM PC či jiný kompatibilní počítač. Oba programy počítají Mandelbrotovo jablko. Na Spectru je hotové asi za 31 minut, na pécéčku (rychlém jako původní IBM PC) to trvá asi 147 minut. Pro Spectrum psáno v Hisoft Pascalu, pro pécéčko v Turbo C 1.5. Použitím vyšší hodinové frekvence se program úměrně zrychlí, ale stejně lze zrychlit i běh Spectra (např. s HD64180 na 9, snese i 12 MHz0. Použití koprocesoru rovněž není čestné. Ale nakonec i ke Spectru si každý může připojit matematický koprocesor (8231, 8232, Am9311 apod.).
Souboj bude pro pécéčko vypadat o něco příznivěji, když se použije Microsoft C a FPa.LIB, která neemuluje koprocesor – čas bude asi poloviční. S emulátorem (FPi.LIB) by to bylo asi jen o 30 procent lepší. S Turbo-paskalskými 6-bajtovými čísly to běhá asi třikrát rychleji. Použitím V20 či V30 CPU lze získat dalších 10 procent. Turbo C 2.0 přidá asi 15-procentní časový bonus.
Takže závěr zní: rychlé výpočty psát na ZX Spectru. Což dělám, protože nemám 8087, který by pomohl, ovšem oproti aritmetickým koprocesorům pro 8-bitové počítače je nehorázně drahý.
Vysvětlení lze hledat v tom, že emulátory počítají na 8 bajtů, Hisoft na 4. Ovšem při deklaraci proměnných jako float je výsledná přesnost stejně 4-bajtová. Navíc to trvá déle než při deklaraci double, neboť se neustále provádějí konverze double-float. Dosud se mi nepodařilo donutit emulátor počítat na menší počet bajtů. Přepsáním konstanty CW_DEFAULT na PC_24 místo PC_64 v CO.ASM jsem si nepomohl, protože Turbo C si to pak stejně přepne na 8 bajtů. Takže nezbývá, než to Spectrum...
Tomáš Ret
{$L-,C-} PROGRAM JABLKO; LABEL 1; CONST MN=100, MM=10; VAR N, X, Y : INTEGER; RE, IM, POM, CRE, CIM : REAL; BEGIN DOT; PAGE; FOR Y := 0 TO 175 DO FOR X := 0 TO 127 DO BEGIN CRE := 0.75-3.0*Y/175; CIM := 3.0*X/255 RE := CRE; IM := CIM; N := 0; REPEAT POM := RE*RE-IM*IM-CRE; IM := 2*RE*IM+CIM; RE := POM; N := N+1; IF N = MN THEN BEGIN PLOT (127+X, Y, 0); PLOT (127-X, Y, 0); END UNTIL (NOT (ABS(RE)+ABS(IM)<MM)); 1: END END.
#include <moje.h> void main() { const in mn=100, mm=10; int d=0, m, n, x, y; float re, im, pom, cre, cim; initgraph(&d, &m, ""); for (y=0; y<176; y++) for (x=0; x<128; x++) { cre=0.75-3.0*y/175; cim=3.0*x/255; re=cre; im=cim; n=0; do { pom = re*re-im*im-cre; im = 2*re*im+cim; re = pom; n = n+1; if(n=mn){ putpixel(127+x, 175-y, 1); putpixel(127-x, 175-y, 1); goto 1; } } while (fabs(re)+fabs(im)<mm); 1: } closegraph(); }