Sei sulla pagina 1di 2

Riduzione a operazioni scalari.

Prendo i vettori, li divido in due e applico questo approccio via via al vettore risultato che viene
prodotto, dimezzando sempre le due componenti che vengono sommate. Pensando a questo
algoritmo con un linguaggio di alto livello, pu essere espresso nel seguente modo: abbiano N
iterazioni, ciascuna iterazione aggiunge al sommatore un elemento del vettore e, questa cosa, non
pu essere vettorializzata, perch si crea una dipendenza di calcolo. La somma viene a
calcolarsi e, solo quando l'accumulatore stato aggiornato, posso sommare un nuovo elemento
del vettore e via dicendo. Se organizziamo lo schema in questo modo, abbiamo un primo vettore di
accumulatori a cui viene sommato, elemento per elemento, un particolare elemento di un vettore.
Viene calcolata la prima somma come elemento di posto 0 del vettore somma + elemento di posto
N/2+1 (del vettore A). Mentre la somma si calcola, non necessariamente dovremo aspettare che si
calcoli il risultato, perch posso fare il calcolo di sum+1 con il vettore A N/2+1 e anche sum+2 con
A N/2+2, e via dicendo. Abbiamo il vettore A, la met di questo vettore A viene copiata nel vettore
sum (quindi A(0) corrisponde a sum+0). A di N/2 diventa il primo elemento di un nuovo vettore A
con i che va da 0 a < N. Per cui questo diventer il nuovo vettore A, "a costo zero". Per fare una
determinata somma non devo aspettare il risultato della somma precedente, mentre quando
avevamo gli elementi del vettore da sommare, dovevamo ottenere il risultato precedente, da
sommare al corrente, per avere il successivo. Nel vettore A, in una prima met e seconda met,
troviamo il primo for che calcola un vettore che ha N/2 elementi, perch va da 0 a VL-1. La 1
iterazione inizializza il vettore sum con il vettore A, in cui trattiamo il vettore sum da 0 a VL-1. E'
come se il vettore da 0 a VL-1 ( gi met) si aggiorna con se stesso, sommato la 2 met del
vettore; invece Il vettore sum da VL a 2(VL-1), che sarebbe la dimensione originale. Stiamo quindi
prendendo il vettore da 0 a VL/2 e stiamo sommando lo stesso vettore da N/2+1 a N. Strutturato
cos, il while, gestisce il progressivo dimezzamento, perch una volta aver eseguito l'operazione
per ogni elemento del vettore, svolgiamo questo ciclo fino a VL>1. Alla prossima iterazione VL
viene dimezzato, il vettore sum che inizialmente era a VL/2 ma dopo la prima iterazione ancora
met, Il primo for essenzialmente crea il vettore sum che viene a manipolarsi, quello che
effettivamente viene svolto come calcolo la seconda parte del codice. Quello che osserveremo
che l'operazione va fatta con una singola operazione vettoriale che riguarder VLR elementi dove
VLR il registro che dice quanti elementi considerare e ogni iterazione questo VLR si dimezzer.
Possiamo scrivere il codice:
Supponiamo in VLR 64, abbiamo questo registro vettoriale:
disegno2

Quello che si pu pensare di fare, anche se crea traffico sulla memoria, caricare dalla memoria il
vettore. Carico la prima met in un vettore, la seconda in un altro ottenendo 2 vettori. Li sommo e,
dato che non troviamo un'operazione, il passaggio forzato andare in memoria. Poi si va in
memoria a rileggere questa parte. Si potrebbe caricare anche una met in un vettore e l'altra met
in un altro vettore ancora, ma non la cosa migliore. L'algoritmo potrebbe essere di aver caricato i
due vettori in partenza, fare la somma in un vettore (che potrebbe anche essere lo stesso che
consideriamo), fare lo STORE del vettore in memoria, dimezzare VLR e fare la LOAD del vettore.
Sommare un vettore sulla sua met ripiegata: per sommarlo dobbiamo caricare in un operando
vettore una parte, l'altra su un altro operando. Poi dobbiamo sommare e il risultato a sua volta
verr ripiegato. Il problema prendere il vettore e caricare le due met: una parte va nella 1
met del vettore. Siccome quest operazione non si pu fare tra vettore e vettore, dovremo
passare dalla memoria. Scriveremo in memoria il vettore e da l lo prenderemo. Per fare questo,
non possiamo scrivere in memoria solo il pezzo di vettore, ma potremmo fare un vettor mask, dove
la seconda met uguale a 1 e fare la STORE del pezzo in memoria Pi veloce, ma
momentaneamente ragiono senza vettor mask. Dopo aver caricato, in memoria, il vettore a partire
da un certo indirizzo devo dimezzare VLR e punto adesso per fare la LOAD non a Rbase ma a
Rbase + VLR( per una LOAD di questi elementi). Li metter in un nuovo registro. Gli altri non c'
bisogno che li carico perch gi presenti. Ora posso fare la somma tra i 2 vettori, somma che dura
VLR. Il risultato lo scrivo in maniera tale da avere gi la somma del vettore ripiegato su se stesso.
Prendo il VLR e lo scrivo in memoria e ripeto tutto quello che ho fatto sino ad ora, dimezzo VLR,
faccio lo STORE e cosi via. Questo processo andr avanti fintanto che che VLR >1. Alla fine avr
un vettore di cui l'ultimo elemento, quello di posto 0, la somma di tutti gli elementi del vettore.