2016-03-22 27 views
1

için tamsayı dizisi döküm için bir __m128i öğe olarak __int16 diziyi temsil etmek deneyin. Döküm __m128i öğesi __int16 dizisine güzel bir şekilde çalışır. Benim örnek kod: thisnasıl SIMD vektör

den

void example() { 
    __m128i v = _mm_set_epi16(1, 2, 3, 4, 5, 6, 7, 8); 
    __int16 *p_i = (__int16 *)&v; 
    for (int i = 0; i < 8; i++) 
     std::cout <<p_i[i] << " "; // 8 7 6 5 4 3 2 1 
    std::cout << "\n"; 

    __int16 i2[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 
    __m128i *p_v2 = (__m128i *) i2; 
    std::cout << __m128i_toString<__int16>(p_v2[0])<< "\n"; //error here 
} 

__m128i_toString<>() Ne kaçırdım? C

+0

Hangi hatayı alıyorsunuz? Benim için iyi çalışıyor (ben __int16'dan 'int16_t'ye değiştirip gerekli' # include's'ı ekledikten sonra). –

+0

Çalışma zamanı hatası. ": 0xC000005: IntelHi.exe içinde '0x000488d9' de işlenmeyen özel durum erişim ihlali '0xFFFFFFF' okuma" –

+3

Oh - muhtemelen sadece hizalama sonra - Verilerinizi hizalamayı deneyin - __attribute __ ((hizalanmış (16))) 'eklemek' listenize ' __int16 dizisi bildirimi. –

cevap

3

Eğer __attribute__((aligned(16))) veya __declspec(align(16)) gibi bir derleyici özgü uzantıları olmadan bir taşınabilir şekilde 16B-hizalama elde etmek için alignas(16) int16_t i2[8] = ... kullanabilir, 11 ++.

the code on godbolt compiled with alignas bakınız. genellikle aynı uzunlukta kısa tamsayı diziler ile aliasing __m128i kaçınmalıdır

Not. Vektörlere veri yollamak, bu sayede tezgahların başarısız bir şekilde gönderilmesini engeller. Bir diziye kaydederek ve daha sonra skaler kod ile işleyerek yatay işlemleri yapmak da sucks compared to SIMD. derleyici gerçek dizi ve işaretçi işlemlerini uzağa optimize etmek olmadığından

_mm_set_epi16() kullanma muhtemelen daha iyi kod yol açacaktır. Bu durumda, (sadece bir dizi için hiçbir depolama olmadan bir salt okunur bir sabitden sadece movaps yapar) başardı. Başlatıcı bir derleme zamanı sabiti değilse, bu kadar iyi sonuç alamayabilirsiniz.