2016-03-04 81 views
2

當我試着使用AVX獲取數據,我得到運行時錯誤 - 分段故障:錯誤AVX循環矢量

int i = 0; 
const int sz = 9; 
size_t *src1 = (size_t *)_mm_malloc(sz*sizeof(size_t), 32); 
size_t *src2 = (size_t *)_mm_malloc(sz*sizeof(size_t), 32); 
size_t *dst = (size_t *)_mm_malloc(sz*sizeof(size_t), 32); 


__m256 buffer = _mm256_load_si256(&src1[i]); 
__m256 buffer2 = _mm256_load_si256(&src2[i+1]); //Segmentation fault in this line 

//Something... 

_mm256_store_si256(dst[i], buffer); 


_mm_free(src1); 
_mm_free(src2); 
_mm_free(dst); 

我使用「_mm256_loadu_si256」內在,而不是解決問題。有人知道爲什麼會發生這種情況?

+2

如果你的緩衝區是一個很小的常量,不要'malloc'!將它們聲明爲本地數組。在C99或GNU C++中,可變長度的本地數組也是非常高效的,只要您知道大小足夠小,不會耗盡堆棧。 –

回答

3

_mm*_load_*內在與對準數據纔有效,而_mm*_loadu_*內部函數允許您與未對齊數據(在性能上的損失)工作。

分段故障告訴您,您嘗試從內存加載到AVX寄存器的值未在正確的邊界上對齊。對於256位版本,這些值必須在32字節的邊界上對齊。

如果您不想支付加載未對齊值的性能損失,那麼您需要確保這些值在32字節邊界上正確對齊。您可以通過插入填充或使用強制對齊的註釋來執行此操作。註釋是特定於編譯器的,在GCC上,你會使用類似__attribute__((aligned(32)))的東西,而在MSVC上,你會使用類似__declspec(align(32))的東西。

這裏的問題,雖然是第二負載你的數組索引是從對齊的內存位置強制負荷。這不能通過屬性/註釋來解決。你將不得不填充值。使用size_t作爲指針類型可能是第一個錯誤。該類型應該是32字節寬。

+0

但是我正確地使用_mm_malloc(sz * sizeof(size_t),32)在32字節邊界上對齊;''這就是爲什麼我不明白髮生了什麼。 –

+2

剛剛更新了我的答案。這就是爲什麼你的第一次加載正常工作。然而,第二個加載並不是,因爲你用'sizeof(size_t)'增加了第一個位置,這不是32字節的倍數。 –

+1

由於C++ 11中存在* alignas說明符*,它允許以標準方式指定對齊要求。例如:'alignas(128)char data [32]'將內存中的數據數組對齊到128個字節。 –