Abbiamo davvero bisogno di auto-vettorizzazione?

3

Sto cercando di capire la parallelizzazione automatica e un caso particolare di ciò è la vettorizzazione automatica. A quanto ho capito, l'auto-vettorializzazione è più o meno:

Il compilatore prende parti del codice che sono "seriali" e le trasforma in un vettore. Ad esempio:

X1=Y1+Z1
X2=Y2+Z2
Xn=Yn+Zn

viene trasformato in

for(int i=0;i<n;i++)
X[i]=Y[i]+Z[i]

Ora sappiamo tutti che la parte più lenta dell'esecuzione del codice è quella dei rami. E se N è davvero molto grande allora il nostro codice rallenterebbe davvero in questo caso. Quindi il compilatore in questo caso srotolerebbe il nostro loop a qualcosa di più simile a

for(int i=0;i<n;i+=4) 
X[i]=Y[i]+Z[i]
X[i+1]=Y[i+1]+Z[i+1]
X[i+2]=Y[i+2]+Z[i+2]
X[i+3]=Y[i+3]+Z[i+3]

Quindi la mia domanda è: perché il compilatore dovrebbe vettorializzare il mio codice se in così tanti casi di azioni eseguite all'interno del ciclo sugli array vengono srotolate a più azioni? Non è controproducente far rotolare il codice in un ciclo all'interno di array e quindi srotolare quel ciclo?

    
posta John Demetriou 11.11.2014 - 09:13
fonte

2 risposte

10

La vettorizzazione automatica in realtà non funziona come pensi tu. Non trasforma il tuo set iniziale di istruzioni in un ciclo: vedi, ad esempio, i risultati di GCC che compila il tuo codice .

In generale, l'auto-vectorizzazione prende un ciclo srotolato e lo trasforma in modo tale che le istruzioni multiple mostrate nell'esempio di un ciclo srotolato siano implementate usando un'unica istruzione a livello di linguaggio assembly.

    
risposta data 11.11.2014 - 09:39
fonte
8

Penso che manchi il passaggio più importante. Dopo che il compilatore ha trasformato le istruzioni multiple in un ciclo, utilizza quindi istruzioni vettoriali come le istruzioni SSE per eseguire più iterazioni del ciclo in parallelo. Se il tuo hardware non ha istruzioni vettoriali, non ci sarebbe alcun motivo. Quindi, invece di srotolare il ciclo come hai mostrato, sarebbe più simile a questo:

for (i=0;i<n;i+=8)
    __vector_add8(&x[i], &y[i], &z[i]);

Dove __vector_add8 compila in un'istruzione vettoriale sull'hardware che ne aggiunge 8 in parallelo.

    
risposta data 11.11.2014 - 09:36
fonte

Leggi altre domande sui tag