25.06.2013 Views

Il Linguaggio Fortran 90/95

Il Linguaggio Fortran 90/95

Il Linguaggio Fortran 90/95

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

148 Array<br />

a(n-1) = a(n-1) + a(n-2)*a(n)<br />

END IF<br />

Come si può facilmente verificare la seconda soluzione presenta tutti i vantaggi associati al loop<br />

unrolling. Infatti:<br />

• Dal momento che ad ogni iterazione vengono eseguite due istruzioni invece di una, il<br />

numero di cicli risulta dimezzato e, con esso, anche il numero di volte che il programma<br />

dovrà verificare la condizione di fine ciclo.<br />

• L’accesso ai registri è resa più efficiente dal fatto che ad ogni iterazione i valori di a(i) e<br />

a(i+1) vengono usati due volte (una volta per ciascuna delle due istruzioni del loop body)<br />

il che porta da tre a due il numero dei registri interrogati per ogni istruzione. In altre<br />

parole, mentre nel primo caso è necessario leggere il contenuto dei tre registria(i), a(i-1)<br />

e a(i+1) per ciascuna delle n−2 iterazioni del ciclo, nel secondo caso è necessario leggere<br />

il contenuto dei quattro registri a(i), a(i-1), a(i+1) e a(i+2) ma soltanto n/2−1 volte.<br />

• <strong>Il</strong> parallelismo del codice può essere sfruttato per far sì che la seconda istruzione venga<br />

eseguita non appena il risultato della prima istruzione sia stato memorizzato sicché contemporaneamente<br />

all’esecuzione della seconda istruzione può aver luogo l’aggiornamento<br />

dell’indice del ciclo e l’esecuzione della successiva prima istruzione del blocco.<br />

3.8.5 Loop blocking<br />

Un’altra operazione spesso assai efficace per migliorare le prestazioni di un programma è quella<br />

nota come loop blocking (o loop tiling) la quale consiste nello scomporre un grosso nido di DO<br />

in una sequenza di cicli innestati più piccoli che operino su blocchi di dati di dimensioni tali<br />

che ciascuno possa essere contenuto per intero nella cache memory. Ma il blocking può servire<br />

anche ad incrementare l’efficienza dell’accesso ai dati contenuti nella cache. La necessità del loop<br />

blocking è illustrata dall’esempio che segue. Si consideri il seguente costrutto la cui funzione è<br />

quella di assegnare alla matrice a la trasposta di b:<br />

DO i=1,n<br />

DO j=1,n<br />

a(i,j) = b(j,i)<br />

END DO<br />

END DO<br />

Come si può notare, l’accesso agli elementi di b avviene con passo unitario mentre l’accesso<br />

agli elementi di a si caratterizza per un passo pari ad n. In questo caso, chiaramente, anche<br />

scambiando i cicli interno ed esterno (ossia effettuando un interchange) non si risolverebbe il<br />

problema ma semplicemente lo si ”invertirebbe”. Ciò che invece può essere fatto è spezzettare<br />

il doppio ciclo in parti più piccole, ad esempio al modo seguente:<br />

DO ti=1,n,64<br />

DO tj=1,n,64

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

Saved successfully!

Ooh no, something went wrong!