La vettorializzazione, in parole semplici, significa ottimizzare l'algoritmo in modo che possa utilizzare le istruzioni SIMD nei processori.
AVX, AVX2 e AVX512 sono i set di istruzioni (Intel) che eseguono la stessa operazione su più dati in un'unica istruzione. per es. AVX512 significa che è possibile operare su 16 valori interi (4 byte) alla volta. Ciò significa che se hai un vettore di 16 numeri interi e vuoi raddoppiare quel valore in ciascun numero intero e quindi aggiungere 10 ad esso. Puoi caricare i valori sul registro generale [a, b, c] 16 volte ed eseguire la stessa operazione oppure puoi eseguire la stessa operazione caricando tutti i 16 valori sui registri SIMD [xmm, ymm] ed eseguire l'operazione una volta. Ciò consente di accelerare il calcolo dei dati vettoriali.
Nella vettorializzazione utilizziamo questo a nostro vantaggio, rimodellando i nostri dati in modo da poter eseguire operazioni SIMD su di esso e accelerare il programma.
L'unico problema con la vettorializzazione sono le condizioni di gestione. Perché le condizioni ramificano il flusso di esecuzione. Questo può essere gestito mascherando. Modellando la condizione in un'operazione aritmetica. per esempio. se vogliamo aggiungere 10 al valore se è maggiore di 100. possiamo farlo entrambi.
if(x[i] > 100) x[i] += 10; // this will branch execution flow.
oppure possiamo modellare la condizione in operazione aritmetica creando un vettore condizione c,
c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask
questo è un esempio molto banale ... quindi, c è il nostro vettore di mascheramento che usiamo per eseguire operazioni binarie basate sul suo valore. Ciò evita la diramazione del flusso di esecuzione e consente la vettorializzazione.
La vettorializzazione è importante quanto la parallelizzazione. Pertanto, dovremmo utilizzarlo il più possibile. Tutti i processori moderni hanno istruzioni SIMD per carichi di lavoro di calcolo pesanti. Possiamo ottimizzare il nostro codice per utilizzare queste istruzioni SIMD usando la vettorializzazione, questo è simile alla parallelizzazione del nostro codice per l'esecuzione su più core disponibili sui processori moderni.
Vorrei partire con la menzione di OpenMP, che consente di vettorializzare il codice usando pragmi. Lo considero un buon punto di partenza. Lo stesso si può dire per OpenACC.