我有一个256位AVX寄存器,包含4个单个精确的复数,存储为实的、虚的、实的、虚的,等等。我目前正在将256位寄存器写回内存,并将其加在内存中,但这似乎效率低下。
如何使用AVX (或AVX2)本质来执行复数水平和?我会接受一个使用程序集的答案,如果没有一个效率相当的答案使用本质。
编辑:为了澄清,如果寄存器包含AR,AI,BR,BI,CR,CI,DR,DI,我想计算复数(AR + BR + CR + DR,AI + BI + CI + DI)。如果结果在256位寄存器中,我可以提取2个单精度浮点数。
Edit2:潜在的解决方案,虽然不一定是最优的.
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);发布于 2016-07-12 15:24:46
一个非常简单的解决方案只需要AVX (而不是AVX2):
__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 }。
https://stackoverflow.com/questions/38331750
复制相似问题