我正在尝试使用 __m128
对复杂的 float 进行一些计算 vector 单位。与__m128
我可以存储两个complex float
s,因为每个复数由两个 float 组成,一个实部和一个虚部。
到目前为止,一切顺利。
当我必须将我的答案“收集”到一个中时,我的问题就出现了 complex float
。假设我有两个__m128
vector ,以及存储在这两个 vector 中的四个复数。例如,我可以使用 _mm_add_ps
将两个 vector (两个和两个 float )添加在一起。内在的,但如何将结果 vector 中的两个复数“减少”为一个复数(两个 float
)并将其存储在数组中?
最佳答案
如果您想对复数使用 SIMD,首先不要以交错/打包格式存储复数。将实部和虚部存储在单独的数组中,这样您就可以并行执行四个复数乘法,而无需任何洗牌(或像 HSUBPS 这样的缓慢水平操作)。
直接回答问题:do the first stage of a horizontal sum :将高 64 降低到另一个 vector 的低 64(使用 _mm_movehl_ps
),然后 _mm_add_ps
,如我对该问题的回答所示。
然后你就可以MOVLPS存储低 2 个 float :void _mm_storel_pi (__m64 *p, __m128 a)
。看来你需要烦人的转换才能使用它:/MOVSD 也可以工作,但需要多一个字节来编码。
And similarly, if I want to grab a complex number from my array and store it twice inside a vector
使用MOVDDUP从内存或其他寄存器广播 64 位。您需要进行一些转换才能使用内在函数,但这很好(它们不会编译为任何指令,并且在 float
数据上使用诸如 MOVDDUP 之类的 double
指令不会有任何损失在任何现有的 CPU 上):
__m128d _mm_loaddup_pd(double const * dp);
__m128d _mm_movedup_pd(__m128d a);
至少它有一个负载内在,不像 PMOVZX ( this design flaw is one of my major pet peeves with intrinsics )。
关于c - 使用 C 中的英特尔内在函数加载和存储复杂 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40237649/