c – SSE比FPU慢?

前端之家收集整理的这篇文章主要介绍了c – SSE比FPU慢?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一大块代码,其中的一部分包含这段代码
result = (nx * m_Lx + ny * m_Ly + m_Lz) / sqrt(nx * nx + ny * ny + 1);

我已经矢量化了如下(一切已经是一个浮动):

__m128 r = _mm_mul_ps(_mm_set_ps(ny,nx,ny,nx),_mm_set_ps(ny,m_Ly,m_Lx));
__declspec(align(16)) int asInt[4] = {
    _mm_extract_ps(r,0),_mm_extract_ps(r,1),2),3)
};
float (&res)[4] = reinterpret_cast<float (&)[4]>(asInt);
result = (res[0] + res[1] + m_Lz) / sqrt(res[2] + res[3] + 1);

结果是正确的然而,我的基准测试表明矢量化版本较慢:

>非矢量化版本需要3750 ms
>矢量化版本需要4050 ms
>直接将结果设置为0(完全删除这部分代码)将整个过程减少到2500 ms

给定矢量化版本只包含一组SSE乘法(而不是四个单独的FPU乘法),为什么它较慢? FPU确实比SSE快,还是在这里有混乱的变数?

(我在手机Core i5上.)

解决方法

您正在花费大量时间将标量值与_mm_set_ps和_mm_extract_ps的SSE寄存器进行移动 – 这正在生成大量指令,其执行时间远远超过使用_mm_mul_ps所带来的任何好处.看看生成的程序集输出,以查看除了单个MULPS指令之外还要生成多少代码.

为了正确向量化,您需要使用128位SSE加载和存储(_mm_load_ps / _mm_store_ps),然后使用SSE随机播放指令在需要的寄存器内移动元素.

另外要注意的是现代cpu(如Core i5,Core i7)有两个标量FPU,每个时钟可以发出2个浮点倍增.因此,SSE对单精度浮点的潜在收益最多只有2倍.如果您有过多的“家务”说明,这很容易损失大部分/所有这2x的好处.

猜你在找的C&C++相关文章