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

X86 如何使用SSE加载std::complex数组的真实部分?,x86,sse,simd,X86,Sse,Simd,由于\u mm\u loadu\u ps()固有函数,我试图在128位寄存器中加载std::complex数组内容的实部 __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&g

由于
\u mm\u loadu\u ps()
固有函数,我试图在128位寄存器中加载
std::complex
数组内容的实部

__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;
m128数据块;
复合物a[4];
a[0]=络合物(1.0,2.0);
a[1]=复合体(3.0,4.0);
a[2]=络合物(5.0,6.0);
a[3]=复合体(7.0,8.0);
数据块=_mm_loadu_ps(&a[0].real());
浮动b[4];
_mm_storeu_ps(b,数据块);
coutNo-这是一个“聚集”操作,仅由AVX(非SSE)支持,而且效率非常低。如果您认真对待SIMD优化,则应更适当地组织数据。如果您真的必须坚持这种数据布局,那么最好的选择可能是加载两个连续的向量,并对它们进行洗牌(排列),以获得一个向量中的所有实部(以及另一个向量中的虚部,如果需要的话),例如

否-这是一个仅由AVX(而非SSE)支持的“聚集”操作,而且效率非常低。如果您认真对待SIMD优化,则应更适当地组织数据。如果您真的必须坚持这种数据布局,那么最好的选择可能是加载两个连续的向量,并对它们进行洗牌(排列),以获得一个向量中的所有实部(以及另一个向量中的虚部,如果需要的话),例如

否-这是一个仅由AVX(而非SSE)支持的“聚集”操作,而且效率非常低。如果您认真对待SIMD优化,则应更适当地组织数据。如果您真的必须坚持这种数据布局,那么最好的选择可能是加载两个连续的向量,并对它们进行洗牌(排列),以获得一个向量中的所有实部(以及另一个向量中的虚部,如果需要的话),例如

否-这是一个仅由AVX(而非SSE)支持的“聚集”操作,而且效率非常低。如果您认真对待SIMD优化,则应更适当地组织数据。如果您真的必须坚持这种数据布局,那么最好的选择可能是加载两个连续的向量,并对它们进行洗牌(排列),以获得一个向量中的所有实部(以及另一个向量中的虚部,如果需要的话),例如


谢谢你的回答。事实上,我必须使用这种数据布局。我将使用您的选项,即使它会增加加载/存储操作的数量,也应该可以。如果您也需要虚部,则加载的数量不会增加,但是是的,如果您只需要实部,则会受到2倍的惩罚。希望你以后能做足够的计算来承担这个成本。回到2010年,我把FFT从
{real,imag}{real,imag}
重写为
{real,real}{imag,imag}
。结果:摆脱所有洗牌后,瞬间加速30%。整个SSE3
addsub
基本上就是一个笑话谢谢你的回答。事实上,我必须使用这种数据布局。我将使用您的选项,即使它会增加加载/存储操作的数量,也应该可以。如果您也需要虚部,则加载的数量不会增加,但是是的,如果您只需要实部,则会受到2倍的惩罚。希望你以后能做足够的计算来承担这个成本。回到2010年,我把FFT从
{real,imag}{real,imag}
重写为
{real,real}{imag,imag}
。结果:摆脱所有洗牌后,瞬间加速30%。整个SSE3
addsub
基本上就是一个笑话谢谢你的回答。事实上,我必须使用这种数据布局。我将使用您的选项,即使它会增加加载/存储操作的数量,也应该可以。如果您也需要虚部,则加载的数量不会增加,但是是的,如果您只需要实部,则会受到2倍的惩罚。希望你以后能做足够的计算来承担这个成本。回到2010年,我把FFT从
{real,imag}{real,imag}
重写为
{real,real}{imag,imag}
。结果:摆脱所有洗牌后,瞬间加速30%。整个SSE3
addsub
基本上就是一个笑话谢谢你的回答。事实上,我必须使用这种数据布局。我将使用您的选项,即使它会增加加载/存储操作的数量,也应该可以。如果您也需要虚部,则加载的数量不会增加,但是是的,如果您只需要实部,则会受到2倍的惩罚。希望你以后能做足够的计算来承担这个成本。回到2010年,我把FFT从
{real,imag}{real,imag}
重写为
{real,real}{imag,imag}
。结果:摆脱所有洗牌后,瞬间加速30%。整个SSE3
addsub
基本上就是一个笑话
__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));