2013-03-19 21 views
8

Przesyłam kod optymalizacji SSE z systemu Windows do systemu Linux. Odkryłem, że poniższy kod, który działa dobrze w MSVC, nie działa w GCC. Kod służy do zainicjowania tablicy __m128i. Każdy __mi28i zawiera 16 int8_t. Dawka jest kompilowana za pomocą gcc, ale wynik nie jest taki, jak oczekiwano. W rzeczywistości, ponieważ gcc definiuje __m128i jako "long long int", kod zainicjuje tablicę taką jak: long long int coeffs_ssse3 [4] = {64, 83, 64, 36}. Przeszukałem go i powiedziano mi, że "Jedynym przenośnym sposobem inicjalizacji wektora jest użycie _is_set_XXX intrinsics". Chciałbym jednak wiedzieć, czy istnieje inny sposób na zainicjowanie tablicy __m128i? Lepsze statycznie i nie trzeba zbytnio modyfikować następującego kodu (ponieważ mam mnóstwo kodu w następującym formacie). Wszelkie sugestie są mile widziane.Jak zainicjować tablicę __m128i statycznie w 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} 
}; 

Odpowiedz

7

Wydaje się, że gcc nie traktuje typy __m128* jako kandydatów do łącznej inicjalizacji. Ponieważ nie są to standardowe typy, zachowanie to będzie się różnić w zależności od kompilatora. Jedno podejście byłoby zadeklarować tablicę jako wyrównany tablicy 8-bitowych liczb całkowitych, a potem po prostu rzucić wskaźnik do niego:

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; 

Jednak nie sądzę tej składni (__attribute__((aligned(x)))) jest obsługiwane przez Visual Studio , więc potrzebujesz tam pewnej sztuczki #ifdef, aby użyć właściwych dyrektyw, aby uzyskać wyrównanie, które chcesz osiągnąć na wszystkich platformach docelowych.

+0

Dziękujemy @Jason! Próbowałem twojej metody i działało bardzo dobrze. (W twojej odpowiedzi uint8_t powinien być int8_t, ponieważ tablica zawiera wartości ujemne. Może to być literówka i możesz edytować swoją odpowiedź, aby była idealna :) – shengbinmeng

Powiązane problemy