Sto cercando di utilizzare la vettorizzazione nel mio compilatore (Microsoft Visual Studio 2013). Uno dei problemi che sto affrontando è che non vuole usare AVX2. Durante l'analisi di questo problema, ho creato il seguente esempio, che calcola una somma di 16 numeri, ognuno di 16 bit.Perché l'auto-vettorizzazione di MSVC non utilizza AVX2?
int16_t input1[16] = {0};
int16_t input2[16] = {0};
... // fill the arrays with some data
// Calculate the sum using a loop
int16_t output1[16] = {0};
for (int x = 0; x < 16; x++){
output1[x] = input1[x] + input2[x];
}
Il compilatore vettorizza questo codice, ma solo per le istruzioni SSE:
vmovdqu xmm1, xmmword ptr [rbp+rax]
lea rax, [rax+10h]
vpaddw xmm1, xmm1, xmmword ptr [rbp+rax+10h]
vmovdqu xmmword ptr [rbp+rax+30h], xmm1
dec rcx
jne main+0b0h
per assicurarsi che il compilatore ha la possibilità di generare il codice AVX2, ho scritto lo stesso calcolo come segue:
// Calculate the sum using one AVX2 instruction
int16_t output2[16] = {0};
__m256i in1 = _mm256_loadu_si256((__m256i*)input1);
__m256i in2 = _mm256_loadu_si256((__m256i*)input2);
__m256i out2 = _mm256_add_epi16(in1, in2);
_mm256_storeu_si256((__m256i*)output2, out2);
Vedo che le due parti del codice sono equivalenti (ovvero, output11
è uguale a output2
dopo l'esecuzione).
Ed emette istruzioni AVX2 per la seconda parte di codice:
vmovdqu ymm1, ymmword ptr [input2]
vpaddw ymm1, ymm1, ymmword ptr [rbp]
vmovdqu ymmword ptr [output2], ymm1
Non voglio riscrivere il mio codice per utilizzare intrinseci, però: dopo aver scritto come un ciclo è molto più naturale, è compatibile con vecchi processori (solo SSE) e ha altri vantaggi.
Quindi, come posso modificare il mio esempio per rendere il compilatore in grado di vettorializzare in modo AVX2?
Sto solo indovinando qui, ma da quello che ho visto dei discorsi su AVX in Visual Studio l'implementazione sembra ancora immatura ed è noto che non sfrutta tutte le ottimizzazioni possibili. Un'altra possibilità è che l'ottimizzatore ha deciso che la migliore prestazione è quella di non utilizzare l'istruzione AVX2 in tutte le circostanze in cui sarebbe possibile. Per esempio ci sono situazioni in cui l'istruzione AVX può causare un errore di cache, il che significa che in realtà finisce più lentamente di un approccio più ingenuo. – sjdowling
Scarica CPU-z per esempio e controlla se la tua CPU supporta AVX o AVX2. Se non lo fa, scommetto che questo è il motivo per cui Visual Studio blocca la tua configurazione – NirMH
@NirMH Penso che dovrebbe essere chiaro dal mio codice che supporta AVX2. Voglio dire, la seconda parte del mio codice riguarda una di queste istruzioni. E ho detto che produce un risultato corretto (il controllo non è in codice, ma l'ho davvero fatto). – anatolyg