Pertanyaan Mengapa vektorisasi otomatis MSVC tidak menggunakan AVX2?


Saya mencoba menggunakan vectorization di compiler saya (Microsoft Visual Studio 2013). Salah satu masalah yang saya hadapi adalah bahwa ia tidak ingin menggunakan AVX2. Saat menyelidiki masalah ini, saya membangun contoh berikut, yang menghitung jumlah 16 angka, masing-masing 16-bit.

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];
}

Compiler vectorizes kode ini, tetapi hanya untuk instruksi 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

Untuk memastikan kompilator memiliki opsi untuk menghasilkan kode AVX2, saya menulis perhitungan yang sama seperti berikut:

// 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);

Saya melihat bahwa dua bagian kode itu setara (yaitu, output11 adalah sama dengan output2 setelah mereka dieksekusi).

Dan ini menghasilkan instruksi AVX2 untuk bagian kedua kode:

vmovdqu  ymm1, ymmword ptr [input2]
vpaddw   ymm1, ymm1, ymmword ptr [rbp]
vmovdqu  ymmword ptr [output2], ymm1

Saya tidak ingin menulis ulang kode saya untuk menggunakan intrinsik, namun: setelah itu ditulis sebagai loop jauh lebih alami, kompatibel dengan prosesor lama (SSE-only), dan memiliki kelebihan lain.

Jadi bagaimana saya bisa mengubah contoh saya untuk membuat compiler dapat vectorize dengan cara AVX2?


7
2017-11-11 12:09


asal


Jawaban:


Visual Studio dengan mudah menghasilkan kode AVX2 ketika melakukan floating point arithmetic. Saya kira ini cukup untuk menyatakan bahwa "VS2013 mendukung AVX2".

Namun, tidak peduli apa yang saya lakukan, VS2013 tidak menghasilkan kode AVX2 untuk perhitungan bilangan bulat (keduanya int16_t maupun int32_t bekerja), jadi saya kira ini tidak didukung sama sekali (gcc menghasilkan AVX2 untuk kode saya di versi 4.8.2; tidak yakin tentang versi sebelumnya).

Jika saya harus melakukan perhitungan int32_t, Saya bisa mempertimbangkan untuk mengubahnya float dan kembali. Namun, karena saya menggunakan int16_t, itu tidak membantu.


0
2018-02-23 20:14