2014-11-11 36 views
7

Vektörleştirmeyi derleyicimde (Microsoft Visual Studio 2013) kullanmaya çalışıyorum. Karşılaştığım sorunlardan biri de AVX2'yi kullanmak istememesi. Bu sorunu araştırırken, her biri 16 bit olan 16 sayıdan oluşan bir toplamı hesaplayan aşağıdaki örneği oluşturdum.MSVC'nin otomatik vektörleştirmesi neden AVX2 kullanıyor?

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

derleyici ama sadece SSE talimatları, bu kodu vektör belirler şu şekildedir:

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 

derleyici AVX2 kodu oluşturmak için seçeneği vardır emin olmak için, ben aynı hesaplamayı yazdı:

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

Kodun iki bölümünün eşdeğer olduğunu görüyorum (yani, output11, yürütüldükten sonra output2'a eşittir).

Ve kod ikinci bölümü için AVX2 talimatları verir: Ben ancak, intrinsics kullanmak için kodumu yeniden yazmak istemiyorum

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

: bir döngü olarak yazılı olan çok daha doğaldır, olduğu eski (yalnızca SSE) işlemcilerle uyumludur ve başka avantajları vardır.

Örneğimi, derleyicinin bunu AVX2 biçiminde düzenleyebilmesi için örneğimi nasıl değiştirebilirim?

+2

Sadece burada düşünüyorum ama Visual Studio'da AVX'teki görüşmelerde gördüğüm şeylerden, uygulama hala olgunlaşmamış gibi görünüyor ve olası tüm optimizasyonlardan yararlanamamakla biliniyor. Diğer bir olasılık ise, en iyi performansın AVX2 talimatını mümkün olduğu her durumda kullanmamaya karar vermesidir. Örneğin, AVX komutunun bir önbellek özniteliğine neden olabileceği durumlar vardır; bu, aslında daha naif bir yaklaşımdan daha yavaş bir şekilde bittiği anlamına gelir. – sjdowling

+0

Örneğin CPU-z'yi indirin ve CPU'nuzun AVX veya AVX2'yi destekleyip desteklemediğini kontrol edin. Değilse, bu yüzden Visual Studio'nun kurulumunuzu engellemesinin nedeni budur. – NirMH

+0

@NirMH Kodumdan AVX2'yi desteklediğinin açık olması gerektiğini düşünüyorum. Demek istediğim, kodumun ikinci kısmı böyle bir talimatı içeriyor. Ve doğru bir sonuç ürettiğinden bahsetmiştim (çek kodu yazmıyor ama ben gerçekten bu kontrolü yaptım). – anatolyg

cevap

0

Visual Studio, kayan nokta aritmetiği yaparken kolayca AVX2 kodu üretir. "VS2013'ün AVX2'yi desteklediğini" bildirmek yeterli.

Ancak, ne olursa olsun ne yaptım, VS2013 tamsayı hesaplamaları (ne int16_t ne de int32_t çalıştı) için AVX2 kodunu üretmedi, bu yüzden bu (gcc sürümü 4.8 benim kodu için AVX2 üreten hiç desteklenmez sanırım. 2; önceki sürümleri hakkında emin değilim).

int32_t üzerinde hesaplamalar yapmak zorunda kaldım, bunları float ve geri dönüştürmeyi düşünebilirim. Ancak, int16_t kullanıyorum, bu yardımcı olmuyor.