2014-11-11 16 views
7

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?

+2

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

+0

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

+0

@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

risposta

0

Visual Studio produce facilmente codice AVX2 durante l'aritmetica in virgola mobile. Suppongo che questo sia sufficiente per dichiarare che "VS2013 supporta AVX2".

Tuttavia, non importa quello che ho fatto, VS2013 ha non produce codice AVX2 per i calcoli interi (né int16_tint32_t lavorato), quindi credo che questo non è supportato a tutti (GCC produce AVX2 per il mio codice alla versione 4.8. 2, non sono sicuro delle versioni precedenti).

Se dovessi eseguire calcoli su int32_t, potrei prendere in considerazione la conversione in float e viceversa. Tuttavia, dal momento che io uso int16_t, non aiuta.

Problemi correlati