2010-12-05 22 views
5

Ben SSE intrinsics kullanarak kodumu optimize etmek çalışıyorum ama ne almak için GGD intrinsics işlemleri yaptıktan sonra ben bir vektör gelen tamsayı değerlerini çıkarmak için iyi bir yol bilmiyorum bir sorun haline çalıştırıyorum ben istemek.128 bit SSE vektöründen 32 bit tamsayı değerlerini yüklemek ve çıkarmak için en etkili yol nedir?

Herkes bunun için iyi bir yol biliyor mu? C programlama yapıyorum ve derleyicim gcc sürüm 4.3.2.

Yardımlarınız için teşekkürler.

+0

Hmm ... 'int * pointer = vectoraddress; * (işaretçi ++) dört kez? – khachik

+0

Tüm işlemlerinizi SSE kayıtlarında yapamayacağınız ve işiniz bittiğinde belleğe geri atabileceğiniz bir neden var mı? –

+0

Denedim ama oldukça çözemedim bazı derleme hataları almaya devam etti? – Kaigi

cevap

7

Bu size sahip SSE minimum destek düzeyi hakkında varsayabiliriz bağlıdır.

SSE2'ye geri dönecek olursanız, 128 bitlik bir vektörden 16 bit öğeyi çıkarmak için kullanabileceğiniz _mm_extract_epi16 (PEXTRW) adresiniz vardır. Bir 32 bit öğenin iki yarısını almak için bunu iki kez çağırmanız gerekir.

SSE'nin daha yeni sürümlerinde (SSE4.1 ve üstü), bir komutta 32 bit öğeyi çıkarabilen _mm_extract_epi32 (PEXTRD) var.

bu performansa kritik döngü içinde değil Alternatif eğer sadece bir sendikaya kullanabilirsiniz, örneğin

typedef union 
{ 
    __m128i v; 
    int32_t a[4]; 
} U32; 
+1

Merhaba Paul, cevabınız için teşekkürler. Bu işlevleri nereden buldunuz (mm_extract_epi16/32)? Onları gcc belgelerinde göremiyorum. -mmmx -msse -msse2 ve -msse3 dahil kullanmama izin vermiyor ve derleyici, örtülü bir işlev bildirimi olduğunu söylüyor. – Kaigi

+2

@Kaigi: 'smmintrin.h olan _mm_extract_epi32' emmintrin.h,' içinde _mm_extract_epi16'. İkincisi için gcc'nin makul bir güncel versiyonuna ihtiyacınız olacak. –

5
_mm_extract_epi32 

özü intrinsics gerçekten en iyi seçenektir ama SSE2 desteklemek gerekirse, bu tavsiye ederim:

inline int get_x(const __m128i& vec){return _mm_cvtsi128_si32 (vec);} 
inline int get_y(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0x55));} 
inline int get_z(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0xAA));} 
inline int get_w(const __m128i& vec){return _mm_cvtsi128_si32 (_mm_shuffle_epi32(vec,0xFF));} 

Ben saptadık/birliği reinterpret_cast eğer herhangi bir int [4] temsili için vektör derleyicinin bir şeyleri belleğe geri getirme eğilimi göstermesi (bu o kadar da kötü olmayabilir) ve bir int olarak geri okur, ancak en son sürümlerin en son sürümleri olup olmadığını görmek için derlemeyi incelemedim. derleyiciler daha iyi kod üretirler.

İlgili konular