Próbuję użyć wektoryzacji w moim kompilatorze (Microsoft Visual Studio 2013). Jednym z problemów, przed którymi stoję, jest to, że nie chce używać AVX2. Podczas badania tego problemu skonstruowałem następujący przykład, który oblicza sumę 16 liczb, z których każda jest 16-bitowa.Dlaczego funkcja automatycznego wektoryzacji MSVC nie korzysta z 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];
}
Kompilator vectorizes tego kodu, ale tylko do instrukcji 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
upewnić się, że kompilator ma możliwość wygenerowania kodu AVX2 pisałem te same obliczenia, co następuje:
// 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);
Widzę, że dwie części kodu są równoważne (tj. output11
jest równa output2
po ich wykonaniu).
I wyprowadza instrukcji AVX2 do drugiej części kodu:
vmovdqu ymm1, ymmword ptr [input2]
vpaddw ymm1, ymm1, ymmword ptr [rbp]
vmovdqu ymmword ptr [output2], ymm1
nie chcę przepisać mój kod do korzystania intrinsics jednak: po to napisany jako pętla jest znacznie bardziej naturalne, jest kompatybilny ze starymi procesorami (SSE) i ma inne zalety.
Jak mogę poprawić mój przykład, aby kompilator mógł wektoryzować w sposób AVX2?
Zgaduję tylko tutaj, ale z tego, co widziałem o rozmowach na AVX w Visual Studio, implementacja wciąż wydaje się niedojrzała i wiadomo, że nie wykorzystuje wszystkich możliwych optymalizacji. Inną możliwością jest to, że optymalizator zdecydował, że najlepszą wydajnością jest niestosowanie instrukcji AVX2 we wszystkich okolicznościach, w których byłoby to możliwe. Na przykład zdarzają się sytuacje, w których instrukcja AVX może powodować brak pamięci podręcznej, co oznacza, że faktycznie kończy się wolniej niż bardziej naiwne podejście. – sjdowling
Pobierz CPU-z na przykład i sprawdź, czy twój procesor obsługuje AVX lub AVX2. Jeśli nie, zakładam, że właśnie dlatego Visual Studio blokuje konfigurację – NirMH
@NirMH Myślę, że powinno być jasne z mojego kodu, że obsługuje AVX2. Mam na myśli, że druga część mojego kodu obejmuje jedną taką instrukcję. I wspomniałem, że daje on poprawny wynik (czek nie jest w kodzie, ale naprawdę sprawdziłem). – anatolyg