25.06.2013 Views

Il Linguaggio Fortran 90/95

Il Linguaggio Fortran 90/95

Il Linguaggio Fortran 90/95

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.

152 Array<br />

b(i+1) = b(i) + a(i)<br />

END DO<br />

In questo caso, ad esempio, uno dei benefici connessi alla fusione in termini di ottimizzazione<br />

dell’accesso ai registri di memoria consiste nel fatto che ciascun termine a(i) deve essere letto<br />

una sola volta e non due come accadeva nella versione originale.<br />

Per fondere due cicli è necessario che i loro indici scorrano fra gli stessi estremi. Se ciò non<br />

accade è talvolta possibile attraverso alcune operazioni di manipolazione (come il peeling o il<br />

normalizing che verranno discussi di seguito) adattare gli estremi in modo da rendere i cicli<br />

compatibili. Due cicli con gli stessi estremi possono essere fusi se non esiste alcuna istruzione<br />

S2 del secondo ciclo che dipenda da una istruzione S1 del primo ciclo. <strong>Il</strong> seguente esempio,<br />

quindi, mostra due cicli che non possono essere sottoposti a fusion in quanto l’istruzione del<br />

secondo ciclo non può avvenire in parallelo con l’istruzione del primo ciclo ma deve essere ad<br />

essa subordinata:<br />

! ciclo originale<br />

DO i=1,n<br />

a(i) = a(i) + k<br />

END DO<br />

DO i=1,n<br />

b(i+1) = b(i) + a(i+1)<br />

END DO<br />

Naturalmente tutto quanto di buono si dica circa dal loop fusion potrebbe sembrare automaticamente<br />

una critica al loop fission e viceversa. In realtà molto dipende da quale aspetto si<br />

vuole ottimizzare, ad esempio la fissione potrebbe essere la scelta giusta su un processore con<br />

una cache limitata o in presenza di array di grandissime dimensioni (in questi casi appare fondamentale<br />

la riduzione della pressione sui registri) o ancora per favorire l’applicazione di altre<br />

operazioni talvolta indispensabili come il loop interchange; la fusione, dal canto suo, permette<br />

una migliore parallelizzazione delle istruzioni e può consentire una drastica riduzione dell’accesso<br />

ai registri di memoria (riducendo così il tempo speso nelle operazioni di lettura/scrittura<br />

”interni”). In ogni caso, del tutto in generale si può dire che in presenza di cicli onerosi (cioè<br />

per grossi valori di n) un codice sottoposto a loop fission verrà eseguito molto più rapidamente<br />

su una macchina seriale, lo stesso ciclo ottimizzato con un loop fusion sarà eseguito molto più<br />

velocemente su un sistema parallelo.<br />

3.8.9 Loop pushing<br />

<strong>Il</strong> loop pushing è un tipo di trasformazione che consiste nello spostare un ciclo dalla procedura<br />

chiamante ad una versione clonata della procedura invocata. Questa operazione può risultare<br />

molto utile per ridurre i tempi di calcolo di un programma (si noti, a tal proposito, che le<br />

chiamate di procedura sono sempre operazioni assai lente) e deve comunque essere effettuata<br />

quasi sempre ”a mano” in quanto sono ben pochi i compilatori <strong>Fortran</strong> che eseguono questo<br />

tipo di ottimizzazione. Un semplice esempio di loop pushing è riportato di seguito:

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

Saved successfully!

Ooh no, something went wrong!