2010-09-29 9 views
5

Chciałbym zoptymalizować poniższy fragment przy użyciu instrukcji SSE, jeśli to możliwe:SIMD (SSE) instrukcja do podziału w GCC

/* 
* the data structure 
*/ 
typedef struct v3d v3d; 
struct v3d { 
    double x; 
    double y; 
    double z; 
} tmp = { 1.0, 2.0, 3.0 }; 

/* 
* the part that should be "optimized" 
*/ 
tmp.x /= 4.0; 
tmp.y /= 4.0; 
tmp.z /= 4.0; 

Czy to w ogóle możliwe?

+1

dlaczego nie możesz pomnożyć przez 0,25? –

Odpowiedz

1

Czy wystarczająca jest tmp.x *= 0.25;?

Należy pamiętać, że instrukcje SSE (w przypadku, gdy chcesz z nich korzystać), ważne jest, aby:

1) wszystkie dostępu do pamięci jest 16 bajtów alighed

2) operacje są wykonywane w pętli

3) nr Int < -> pływak lub unosić < -> podwójne konwersji przeprowadza

4) unikać, jeśli to możliwe podziały

+0

nie. w mojej aplikacji 4.0 zostanie zastąpiony przez zmienną. – guest

+0

dlaczego potrzebuję pętli? że to się opłaca? – guest

+0

W każdym razie, aby uzyskać pomoc, musisz opublikować więcej kodu, a nie tylko linii z podziałem. – ruslik

1

Użyłem rozszerzenia SIMD pod Windowsem, ale jeszcze nie pod Linuksem. Mając to na uwadze, powinieneś być w stanie skorzystać z operacji SSE, która podzieli 4 wektor float przez inny 4 wektor float. Ale używasz podwójnych, więc będziesz chciał wersji SSE2 DIVPD. Prawie zapomniałem, upewnij się, że korzystasz z przełącznika -msse2.

Znalazłem stronę, która zawiera szczegóły niektórych wbudowanych GUC SSE. Wygląda trochę staro, ale powinien być dobrym początkiem.

http://ds9a.nl/gcc-simd/

+0

Nie mogę jednak znaleźć odpowiedniego GCC wbudowanego dla DIVPD. – guest

+0

Oto pełna lista prosto http: //gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/X86-Built_002din-Functions.html –

+0

v2df __builtin_ia32_divpd (v2df, v2df), wydaje się być tym, czego szukałem. dzięki. – guest

1

Wewnętrzna szukasz jest _mm_div_pd. Oto działający przykład, który powinien wystarczyć, aby skierować Cię we właściwym kierunku:

#include <stdio.h> 

#include <emmintrin.h> 

typedef struct 
{ 
    double x; 
    double y; 
    double z; 
} v3d; 

typedef union __attribute__ ((aligned(16))) 
{ 
    v3d a; 
    __m128d v[2]; 
} u3d; 

int main(void) 
{ 
    const __m128d vd = _mm_set1_pd(4.0); 
    u3d u = { { 1.0, 2.0, 3.0 } }; 

    printf("v (before) = { %g %g %g }\n", u.a.x, u.a.y, u.a.z); 

    u.v[0] = _mm_div_pd(u.v[0], vd); 
    u.v[1] = _mm_div_pd(u.v[1], vd); 

    printf("v (after) = { %g %g %g }\n", u.a.x, u.a.y, u.a.z); 

    return 0; 
}