如何使用SSE加载std :: complex数组的实部?

时间:2014-08-13 08:56:53

标签: x86 sse simd

由于std::complex<float>内在函数,我试图在128位寄存器中加载_mm_loadu_ps()数组内容的实部。

__m128 data_block;

complex<float> a[4];
a[0] = complex<float>(1.0, 2.0);
a[1] = complex<float>(3.0, 4.0);
a[2] = complex<float>(5.0, 6.0);
a[3] = complex<float>(7.0, 8.0);

data_block = _mm_loadu_ps(&a[0].real());

float b[4];
_mm_storeu_ps(b, data_block);

cout << b[0] << " " << b[1] << " " << b[2] << " " << b[3] << endl;

我得到输出1 2 3 4而不是1 3 5 7。 这是因为_mm_loadu_ps()函数在作为参数给出的地址之后加载了4个数据。

我知道我可以使用中间数组,但我的问题是: 是否存在允许执行加载的内部函数,以及分别使用偏移量执行的存储操作?所以我可以给sizeof(float)作为偏移量,只加载我的数组的实部并在处理后存储它们。

提前谢谢。

1 个答案:

答案 0 :(得分:3)

不 - 这是一个“聚集”操作,只有AVX(不是SSE)支持,效率也很低。如果您认真对待SIMD优化,则应该更合理地组织数据。如果你真的必须坚持使用这种数据布局,那么最好的选择可能是加载两个连续的向量并对它们进行混洗(置换)以将所有真实部分放在一个(如果需要的话,将虚部放在另一个中),例如

__m128 v0 = _mm_loadu_ps(&a[0].real());
__m128 v1 = _mm_loadu_ps(&a[2].real());
__m128 v_real = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(2, 0, 2, 0));
__m128 v_imag = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(3, 1, 3, 1));