2014-09-14 3 views
0

다음과 같은 루프가 있습니다.증분 루프의 경우 SSE를 사용하는 방법은 무엇입니까?

for(int i = 0;i < 28;i++) 
{ 
    a[i] = addr + flag; 
    flag = flag + b[i]; 
} 

여기서 각 값에 대한 플래그를 증가시킵니다. i. 따라서이 경우 SSE를 사용하여 루프 내부의 기능을 구현할 수 있습니다.

+0

최종 목표는 무엇인가, 여기에 사용되는 모든 변수의 유형은 무엇입니까? –

+0

모든 것이 정수입니다. i의 각 값에 대해 a [i]를 계산 한 다음 플래그를 생성합니다. SSE를 사용하여 수행 할 수있는 방법이 있습니까? –

+0

플래그가 이전 평가에 따라 다르기 때문에 불가능하다고 생각합니다. – alkino

답변

1

기본적으로 접두사 합계 (일명 누적 합계)입니다. 나는 SSE and AVX으로 이것을했다. 다음 코드는 SSE2를 사용하여 원하는 것을 수행해야합니다.

#include <x86intrin.h> 
#include <stdio.h> 

inline __m128i scan_SSE(__m128i x) { 
    x = _mm_add_epi32(x, _mm_slli_si128(x, 4)); 
    x = _mm_add_epi32(x, _mm_slli_si128(x, 8)); 
    return x; 
} 

void foo(int *a, int *b, const int n, const int addr, int flag) { 
    for(int i=0; i<n; i++) { 
     a[i] = addr + flag; 
     flag = flag + b[i]; 
    } 
    printf("flag %d\n", flag); 
} 

void foo_SSE(int *a, int *b, const int n, const int addr, int flag) { 
    __m128i offset = _mm_setzero_si128(); 
    __m128i k4 = _mm_set1_epi32(addr+flag-b[0]); 

    int i; 
    for (i = 0; i < n-3; i+=4) { 
     __m128i x = _mm_load_si128((__m128i*)&b[i]); 
     __m128i out = scan_SSE(x); 
     out = _mm_add_epi32(out, offset); 
     offset = _mm_shuffle_epi32(out, _MM_SHUFFLE(3, 3, 3, 3)); 
     out = _mm_add_epi32(out, k4); 
     _mm_store_si128((__m128i*)&a[i], out); 

    }  
    for(; i<n; i++) { 
     a[i] = addr + flag; 
     flag = flag + b[i]; 
    } 
    flag = a[n-1]-addr+b[0]; 
    printf("flag %d\n", flag); 
} 

int main() { 
    const int n = 24; 
    int a[n], b[n]; 

    for(int i=0; i<n; i++) a[i] = 1; 

    foo(b,a, n, 2,3); 
    for(int i=0; i<n; i++) printf("%d ", b[i]); printf("\n"); 

    foo_SSE(b,a, n, 2,3); 
    for(int i=0; i<n; i++) printf("%d ", b[i]); printf("\n"); 
} 

출력 :

flag 27 
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 
flag 27 
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 
+0

안녕 .. 정말 고마워. 나는 tis를 테스트하고 u에게 알려줄 것이다 ... 잠시 동안 cygwin에서 SSE를 활성화하는 방법을 알고있다. –

+0

@vinodc, 나는 코드를 수정했다. 나는 깃발을 출력하는 것을 잊었다. 나는 나이에 cygwin을 사용하지 않았다. 64 비트 모드로 컴파일하면 기본적으로 SSE2가 활성화되어야합니다. 그렇지 않으면 GCC가 명령 행 옵션에'-msse2'를 추가하십시오. –

+0

정말 고마워. 작은 설명. 4 개의 랜덤 값을 sse 레지스터에로드 할 수 있습니까? –