Очень сложно (если возможно) написать «высокооптимизированную версию AVX2» комплексного пресса, поскольку способ определения комплексных чисел в стандарте предотвращает (особенно из-за всех угловых случаев inf / nan) большую оптимизацию.
Однако, если вас не волнует правильность, вы можете просто использовать -ffast-math
, и некоторые компиляторы оптимизируют код для вас.Смотрите вывод gcc: https://godbolt.org/z/QbZlBI
Вы также можете взять этот вывод и создать свою собственную функцию abs со встроенной сборкой.Но да, как уже упоминалось, если вам действительно нужна производительность, вы, вероятно, захотите поменять std::complex
на что-то другое.
Я смог получить приличный вывод для вашего конкретного случая со всеми необходимыми перемешиваниями:заполнение вручную небольших массивов re
и im
.См .: https://godbolt.org/z/sWAAXo Это может быть тривиально расширено для ymm
регистров.
В любом случае, вот окончательное решение, адаптированное из этого ответа SO , в котором используются встроенные функции в сочетании с умнымоптимизация компилятора:
#include <complex>
#include <cassert>
#include <immintrin.h>
static inline void cabs_soa4(const float *re, const float *im, float *b) {
__m128 x4 = _mm_loadu_ps(re);
__m128 y4 = _mm_loadu_ps(im);
__m128 b4 = _mm_sqrt_ps(_mm_add_ps(_mm_mul_ps(x4,x4), _mm_mul_ps(y4,y4)));
_mm_storeu_ps(b, b4);
}
void computeAbsolute (const std::complex<float>* src,
float* realValuedDestinationVec,
int vecLength)
{
for (int i = 0; i < vecLength; i += 4) {
float re[4] = {src[i].real(), src[i + 1].real(), src[i + 2].real(), src[i + 3].real()};
float im[4] = {src[i].imag(), src[i + 1].imag(), src[i + 2].imag(), src[i + 3].imag()};
cabs_soa4(re, im, realValuedDestinationVec);
}
}
, которая компилируется в простые
_Z15computeAbsolutePKSt7complexIfEPfi:
test edx, edx
jle .L5
lea eax, [rdx-1]
shr eax, 2
sal rax, 5
lea rax, [rdi+32+rax]
.L3:
vmovups xmm0, XMMWORD PTR [rdi]
vmovups xmm2, XMMWORD PTR [rdi+16]
add rdi, 32
vshufps xmm1, xmm0, xmm2, 136
vmulps xmm1, xmm1, xmm1
vshufps xmm0, xmm0, xmm2, 221
vfmadd132ps xmm0, xmm1, xmm0
vsqrtps xmm0, xmm0
vmovups XMMWORD PTR [rsi], xmm0
cmp rax, rdi
jne .L3
.L5:
ret
https://godbolt.org/z/Yu64Wg