2013-03-19 12 views
8

Sto eseguendo il porting di un codice di ottimizzazione SSE da Windows a Linux. E ho scoperto che il seguente codice, che funziona bene in MSVC, non funzionerà in GCC. Il codice serve per inizializzare un array di __m128i. Ogni __mi28i contiene 16 int8_t. Si somministra con gcc ma il risultato non è come previsto. In realtà, poiché gcc definisce __m128i come "long long int", il codice inizializzerà un array come: long long int coeffs_ssse3 [4] = {64, 83, 64, 36}. Ho cercato su Google e mi è stato detto che "L'unico modo portatile per inizializzare un vettore è usare _mm_set_XXX intrinsics." Tuttavia, voglio sapere c'è qualche altro modo per inizializzare l'array __m128i? Migliore staticamente e non è necessario modificare molto il codice seguente (poiché ho tonnellate di codice nel seguente formato). Qualsiasi suggerimento è apprezzato.Come inizializzare l'array __m128i staticamente in gcc?

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} 
}; 

risposta

7

Sembra che gcc non tratti i __m128* tipi come candidati per l'inizializzazione aggregata. Dal momento che non sono tipi standard, questo comportamento varierà dal compilatore al compilatore. Un approccio potrebbe essere quello di dichiarare la matrice come una matrice allineata di interi a 8 bit, poi basta lanciare un puntatore ad esso:

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; 

Tuttavia, non credo che questa sintassi (__attribute__((aligned(x)))) è supportato da Visual Studio , quindi hai bisogno di alcuni stratagemmi #ifdef per utilizzare le giuste direttive per ottenere l'allineamento che desideri su tutte le piattaforme di destinazione.

+0

Grazie @Jason! Ho provato il tuo metodo e ha funzionato molto bene. (Nella tua risposta, uint8_t dovrebbe essere int8_t dato che la matrice contiene valori negativi. Potrebbe trattarsi di un errore di battitura e potresti modificare la risposta per renderla perfetta :) – shengbinmeng

Problemi correlati