2013-03-19 52 views
8

我正在將一些SSE優化代碼從Windows移植到Linux。我發現以下代碼在MSVC中運行良好,在GCC中不起作用。代碼是初始化一個__m128i數組。每個__mi28i包含16個int8_t。它用gcc編譯,但結果並不如預期。實際上,當gcc將__m128i定義爲「long long int」時,代碼將初始化一個數組,如:long long int coeffs_ssse3 [4] = {64,83,64,36}。我搜索了一下,並被告知:「初始化矢量的唯一便攜方式是使用_mm_set_XXX內在函數。」但是,我想知道有沒有其他方法來初始化__m128i數組?靜態更好,不需要修改以下代碼(因爲我有以下格式的大量代碼)。任何建議表示讚賞。如何在gcc中靜態初始化__m128i數組?

static const __m128i coeffs_ssse3[4] = 
{ 
    { 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0}, 
    { 83, 0, 36, 0,-36,-1,-83,-1, 83, 0, 36, 0,-36,-1,-83, -1}, 
    { 64, 0,-64,-1,-64,-1, 64, 0, 64, 0,-64,-1,-64,-1, 64, 0}, 
    { 36, 0,-83,-1, 83, 0,-36,-1, 36, 0,-83,-1, 83, 0,-36,-1} 
}; 

回答

7

看來,gcc不能治療__m128*類型爲對集合初始化候選人。由於它們不是標準類型,因此這種行爲因編譯器而異。一種方法是將數組聲明爲8位整數的對齊陣列,然後只投它的指針:

static const int8_t coeffs[64] __attribute__((aligned(16))) = 
{ 
    64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 64, 0, 
    83, 0, 36, 0,-36,-1,-83,-1, 83, 0, 36, 0,-36,-1,-83, -1, 
    64, 0,-64,-1,-64,-1, 64, 0, 64, 0,-64,-1,-64,-1, 64, 0, 
    36, 0,-83,-1, 83, 0,-36,-1, 36, 0,-83,-1, 83, 0,-36,-1 
}; 
static const __m128i *coeffs_ssse3 = (__m128i *) coeffs; 

不過,我不認爲這句法(__attribute__((aligned(x))))是由Visual Studio支持,所以你需要一些#ifdef的技巧來使用正確的指令來達到你想要的所有目標平臺上的對齊。

+0

謝謝@Jason!我試過你的方法,它工作得很好。 (在你的答案中,uint8_t應該是int8_t,因爲數組包含負值。這可能是一個錯字,你可以編輯你的答案,使其完美:) – shengbinmeng 2013-03-19 14:29:50