저는 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);
우리는 코드 사이트입니다. 간단한 예제를 통해 더 쉽게 원하는 것을 설명 할 수 있습니다. 즉, 나는 그 문제를 놓치고있다. 예, AVX는 차선이 2 개인 미친 디자인이지만이 경우에는 상처를주지 않습니다. 실수 부분을 다른 레인 (비트 0 : 127과 128 : 255)에 하나의 레인에 가상 셔플하십시오. 레인에 수평 추가를하십시오. 결과는 0시 31 분 및 128시 159 분에 종료됩니다. – MSalters
목표는 무엇입니까? 어쩌면 2 개의 AVX 레지스터에 8 개의 복소수를 저장하는 것을 고려해보십시오. 하나의 실수 부분과 다른 부분의 허수 부. 그것은 당신의 목표가 무엇인지에 달려 있습니다. –
@ Zboson 내 목표는 질문에 언급 된 그대로입니다. 데이터는 실수 값과 허수 값이 교대로 저장되므로 변경 될 수 없습니다. 편집에서 제안한 솔루션은 실수와 허수 성분을 합산하기 위해 분리하지만 입력 데이터는 실수와 허수의 교대로 나타납니다. – user1777820