2014-02-07 30 views
1

我有一個函數C與原型void f(__m128i *x)。裏面這個功能我現在呼叫_mm_shuffle_epi8(*x, MASK)其中MASK是一些常數__m128i類型。當我運行代碼時,我得到了一個分段錯誤,而Valgrind發現它實際上是這條線上發生的一般保護錯誤。_mm_shuffle_epi8上的一般保護錯誤

這可能是什麼原因造成的,我該如何解決?

小工作示例:

#include <wmmintrin.h> 
#include <smmintrin.h> 

#define BSWAP_MASK    _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) 
#define ALIGN(n)    __attribute__ ((aligned(n))) 

static inline void g(const unsigned char *in, unsigned char *out) { 
    __m128i tmp = _mm_load_si128 ((__m128i*)in); 
    _mm_store_si128((__m128i*)out, tmp); 
} 

void f(__m128i *res) { 
    g((unsigned char*)&res, (unsigned char*)&res); 
    *res = _mm_shuffle_epi8(*res, BSWAP_MASK); 
} 

int main() { 
    ALIGN(16) __m128i x = _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); 
    f(&x); 
} 
+0

錯誤對齊? –

+0

'x' 16字節的內存是否對齊? –

+0

它是16字節對齊是 –

回答

1

爲可疑,你有對齊問題。

如果您沒有正確對齊數據或使用函數加載和存儲未對齊的地址,則結果會崩潰。

如果你想使用未對齊的地址,那麼這個修復該問題:

static inline void g(const unsigned char *in, unsigned char *out) { 
    //__m128i tmp = _mm_load_si128 ((__m128i*)in); 
    __m128i tmp = _mm_loadu_si128 ((__m128i*)in); 
    //_mm_store_si128((__m128i*)out, tmp); 
    _mm_storeu_si128((__m128i*)out, tmp); 
} 

至於爲什麼連接失敗,使該變量正確對齊,看到Are stack variables aligned by the GCC __attribute__((aligned(x)))?和答案在那裏。

如果你在linux上,你可以使用posix_memalign()函數。