12.06.2013 Views

1 - Amiga Magazine Online

1 - Amiga Magazine Online

1 - Amiga Magazine Online

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

swap d4<br />

moveq #0,d5<br />

m0ve.w OnScreenDim,d5<br />

divu.1 d5,d4 ; d4=Step<br />

moveq #O,dl ; dl=v<br />

m0ve.w #320,d3 ;d3=Dimensioni riga schermo<br />

m0ve.w yO,d5<br />

mu1u.w d3,d5<br />

move.1 ScreenBase,a2<br />

adda.w xO,a2<br />

adda.1 d5,a2 ;a2=ptr allo schermo<br />

m0ve.w OnScreenDim,d7 ;d7=y<br />

subq.w #l,d7<br />

loopy :<br />

moveq #O,dO ; dO=u<br />

move.1 dl,d5<br />

swap d5<br />

mu1u.w TextureDim,d5<br />

move.1 TextureBase,aO<br />

adda.1 d5,aO<br />

move.1 a2,al<br />

m0ve.w OnScreenDim,d6 ;d6=x<br />

subq.w #l,d6<br />

loopx :<br />

swap do<br />

m0ve.b (aO,dO.w),(al)+ ;Scrive il pixel<br />

swap do<br />

add.1 d4,dO ; u+=Step<br />

dbra d6,loopx<br />

;Passa alla prossima riga di schermo<br />

adda.w d3,a2<br />

add.1 d4,dl ;v+=Step<br />

dbra d7,loopy<br />

Lasciamo le altre ottimizzazioni, per esempio quelle rela-<br />

tive alle moltiplicazioni e agli accessi assoluti alla memo-<br />

ria, come esercizio.<br />

Si osservi ora il ciclo identificato dalla label loopx, la cui<br />

ottimizzazione è di vitale importanza. Infatti è in questo<br />

piccolo ciclo che il processore impiega la maggior parte<br />

del proprio tempo, e le tecniche per ottimizzarlo sono al-<br />

meno due, entrambe molto efficaci.<br />

Iniziamo con la tecnica più importante e meno conosciuta,<br />

quella che ritroveremo in tutti i cicli di texture<br />

mapping ben ottimizzati. Come avrete notato, la prima<br />

istruzione di swap serve per mettere nella word bassa di<br />

do la parte intera di u, in modo da poterla utilizzare nell'indirizzamento<br />

indiretto indicizzato, necessario per leggere<br />

il pixel dalla texture. Subito dopo, una seconda<br />

istruzione di swap riporta do nel formato originario, necessario<br />

alla istruzione di somma. È possibile eliminare<br />

dal ciclo le due istruzioni di swap? Ebbene, la risposta è<br />

sì.<br />

Normalmente, la parte intera di un numero in virgola<br />

fissa è contenuta nella parte alta di un registro, mentre<br />

la parte frazionaria è contenuta nella parte bassa, ma<br />

nulla ci vieta di invertire tale ordine, in modo che la<br />

parte intera sia già dove ci interessa e che le due istru-<br />

zioni di swap non siano più necessarie. Owiamente en-<br />

trambi gli addendi devono essere rappresentati nello<br />

stesso formato. Nascono però due problemi. Nella som-<br />

ma di due long, il riporto si propaga, come è logico che<br />

sia, dalla word bassa a quella alta, cosa che nel nostro<br />

caso non deve assolutamente accadere. Sarebbe infatti<br />

totalmente sbagliato che un eventuale overflow della<br />

parte intera andasse a intaccare la parte frazionaria (pri-<br />

mo problema). Al contrario, il riporto deve propagarsi<br />

dalla word alta a quella bassa (secondo problema).<br />

Il primo problema, nel nostro caso, è inconsistente, in<br />

quanto la parte intera dei due valori da sommare può as-<br />

sumere il valore massimo di TextureDim (128), per cui in<br />

nessun caso pratico è possibile che si verifichi un over-<br />

flow della word bassa.<br />

La soluzione del secondo problema è un po' più com-<br />

plessa. A prima vista, per fare in modo che il riporto di<br />

una somma si propaghi dalla word alta a quella bassa,<br />

bisognerebbe utilizzare due istruzioni di somma:<br />

L'istruzione addx di somma estesa (con d2=0) serve<br />

esclusivamente a sommare alla parte bassa di do il ri-<br />

porto della somma precedente. In questo modo, però,<br />

sono necessarie due istruzioni di somma e un registro<br />

(d2) in più che, tra l'altro, potrebbe non essere libero.<br />

Possiamo allora pensare di utilizzare la sola istruzione di<br />

somma estesa, avendo l'accortezza di evitare altre istru-<br />

zioni che modificano il flag di X:<br />

loopx:<br />

m0ve.b (aO,dO.w),(al)+ ;Scrive il pixel<br />

addx.1 d4,dO ; u+=Step<br />

dbra d6,loopx<br />

Il ciclo appena descritto funziona abbastanza bene, ma<br />

non è perfetto, in quanto il riporto (costituito come<br />

sappiamo dal flag X) viene sommato alla word bassa di<br />

do con un ciclo di ritardo, generando delle lievi impre-<br />

cisioni. Tali imprecisioni sono del tutto impercettibili,<br />

ma se è possibile eliminarle facilmente, perché non far-<br />

lo? A tale scopo è infatti sufficiente, subito prima del ci-<br />

clo loopx, sommare a u la sola parte frazionaria di Step<br />

move.1 d4,d2 ;Copia Step in un registro<br />

c1r.w d2 ;Elimina la parte intera<br />

add.1 d2,dO ;Somma a u la parte frazionaria

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!