2016-07-12 4 views
0

저는 4 개의 단 정밀도 복소수를 포함하는 256 비트 AVX 레지스터를 실제, 가상, 실제, 가상 등으로 저장했습니다. 현재 전체 256 비트 레지스터를 메모리에 다시 쓰고 거기에서 합산하고 있지만 비효율적 인 것처럼 보입니다.AVX, 단일 정밀도 복소수의 가로 합계?

어떻게 AVX (또는 AVX2) 내장 함수를 사용하여 복소수 수평 합계를 수행 할 수 있습니까? 내장 함수를 사용하여 비교 가능한 효율성을 가진 대답이 없으면 어셈블리를 사용하여 대답을 수락합니다.

편집 : 레지스터에 AR, AI, BR, BI, CR, CI, DR, DI가 포함되어있는 경우 명확하게하려면 복소수 (AR + BR + CR + DR, AI + BI + CI) + DI). 결과가 256 비트 레지스터에 있으면 2 개의 단 정밀도 부동 소수점 수를 추출 할 수 있습니다.

Edit2가이 : 잠재적 인 솔루션,하지만 반드시 최적이 아닌 ... 단지 AVX (안 AVX2)가 필요합니다

float hsum_ps_sse3(__m128 v) { 
    __m128 shuf = _mm_movehdup_ps(v);  // broadcast elements 3,1 to 2,0 
    __m128 sums = _mm_add_ps(v, shuf); 
    shuf  = _mm_movehl_ps(shuf, sums); // high half -> low half 
    sums  = _mm_add_ss(sums, shuf); 
    return  _mm_cvtss_f32(sums); 
} 

float sumReal = 0.0; 
float sumImaginary = 0.0; 

__m256i mask = _mm256_set_epi32 (7, 5, 3, 1, 6, 4, 2, 0); 

// Separate real and imaginary. 
__m256 permutedSum = _mm256_permutevar8x32_ps(sseSum0, mask); 
__m128 realSum = _mm256_extractf128_ps(permutedSum , 0); 
__m128 imaginarySum = _mm256_extractf128_ps(permutedSum , 1); 

// Horizontally sum real and imaginary. 
sumReal = hsum_ps_sse3(realSum); 
sumImaginary = hsum_ps_sse3(imaginarySum); 
+0

우리는 코드 사이트입니다. 간단한 예제를 통해 더 쉽게 원하는 것을 설명 할 수 있습니다. 즉, 나는 그 문제를 놓치고있다. 예, AVX는 차선이 2 개인 미친 디자인이지만이 경우에는 상처를주지 않습니다. 실수 부분을 다른 레인 (비트 0 : 127과 128 : 255)에 하나의 레인에 가상 셔플하십시오. 레인에 수평 추가를하십시오. 결과는 0시 31 분 및 128시 159 분에 종료됩니다. – MSalters

+0

목표는 무엇입니까? 어쩌면 2 개의 AVX 레지스터에 8 개의 복소수를 저장하는 것을 고려해보십시오. 하나의 실수 부분과 다른 부분의 허수 부. 그것은 당신의 목표가 무엇인지에 달려 있습니다. –

+0

@ Zboson 내 목표는 질문에 언급 된 그대로입니다. 데이터는 실수 값과 허수 값이 교대로 저장되므로 변경 될 수 없습니다. 편집에서 제안한 솔루션은 실수와 허수 성분을 합산하기 위해 분리하지만 입력 데이터는 실수와 허수의 교대로 나타납니다. – user1777820

답변

3

한 매우 간단한 해결책은 :

__m128i v0 = _mm256_castps256_ps128(v);  // get low 2 complex values 
__m128i v1 = _mm256_extractf128_ps(v, 1); // get high 2 complex values 
v0 = _mm_add_ps(v0, v1);      // add high and low 
v1 = _mm_shuffle_ps(v0, v0, _MM_SHUFFLE(1, 0, 3, 2)); 
v0 = _mm_add_ps(v0, v1);      // combine two halves of result 

결과는 v0로 될 것 { sum.re, sum.im, sum.re, sum.im }.

+0

이상한 - CR/LF 라인 결말과 관련이 있을지도 모릅니다. –

+0

하하하 ... 나는 최근에 설치 한 Firefox에서 임의의 에이전트 Spoofer를 사용하고 있습니다. 외관상으로는, 그것을 무작위로 선택한 프로파일 (IE10이라고 생각합니다). 새로운 임의의 프로필을 선택하면 올바르게 표시됩니다. –

+0

아하 - 그건 안도의 문제 야. 나는 일찍 편집을 했어. 게시물에 아무 것도 보이지 않았다. –