首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比FPU慢?

比FPU慢?
EN

Stack Overflow用户
提问于 2012-01-13 07:51:16
回答 3查看 4.1K关注 0票数 9

我有一大段代码,其中一部分包含了以下代码:

代码语言:javascript
复制
result = (nx * m_Lx + ny * m_Ly + m_Lz) / sqrt(nx * nx + ny * ny + 1);

我将其矢量化如下(一切都已经是float):

代码语言:javascript
复制
__m128 r = _mm_mul_ps(_mm_set_ps(ny, nx, ny, nx),
                      _mm_set_ps(ny, nx, m_Ly, m_Lx));
__declspec(align(16)) int asInt[4] = {
    _mm_extract_ps(r,0), _mm_extract_ps(r,1),
    _mm_extract_ps(r,2), _mm_extract_ps(r,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
  • result直接设置为0 (并完全删除这部分代码),将整个过程减少到2500 ms

< code >f 212。

既然矢量化版本只包含一组SSE乘法(而不是四个单独的FPU乘法),为什么要慢一些呢?FPU确实比SSE更快,还是这里有一个混乱的变量?

(我在移动核心i5上。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-13 07:53:32

您正在花费大量时间使用_mm_set_ps_mm_extract_ps将标量值移动到SSE寄存器/从SSE寄存器中移动--这将生成大量指令,其执行时间将远远超过使用_mm_mul_ps带来的任何好处。查看生成的程序集输出,看看除了单个MULPS指令之外,还生成了多少代码。

要正确地向量化这一点,您需要使用128位SSE加载和存储(_mm_load_ps/_mm_store_ps),然后在需要时使用SSE洗牌指令在寄存器中移动元素。

还有一点要注意--现代CPU,如核心i5、核心i7,有两个标量FPU,每个时钟可以发出2个浮点乘法。因此,SSE对单精度浮点的潜在好处最多只有2倍。如果你有过多的“家务管理”指令,你很容易失去大部分/所有这2倍的好处,就像这里的情况。

票数 17
EN

Stack Overflow用户

发布于 2012-01-13 08:02:11

有几个问题:

  1. 您将不会看到在这种操作中使用SSE指令有多大好处,因为SSE指令应该更适合并行操作(也就是说,同时乘以几个值)。您所做的是误用SSE
  2. 不设置值,使用指向数组中第一个值的指针,但是您的值不在数组中,
  3. 不提取值并将值复制到数组中。这也是对SSE的滥用。结果应该在一个数组中。
票数 4
EN

Stack Overflow用户

发布于 2012-01-13 07:54:48

我的看法是,当使用FPU加载下一个值时,处理器有时间计算第一个乘法。SSE必须首先加载所有值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8847429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档