5

案例一

假设你有一个小班:

class Point3D
{
private:
  float x,y,z;
public:
  operator+=()
  
  ...etc
};

Point3D &Point3D::operator+=(Point3D &other)
{
  this->x += other.x;
  this->y += other.y;
  this->z += other.z;
}

天真的使用 SSE 会简单地用一些内在函数替换这些函数体。但是我们会期望这会产生很大的不同吗?MMX 曾经涉及昂贵的状态变化 IIRC,SSE 还是它们就像其他指令一样?即使没有直接的“使用 SSE”开销,将值移入 SSE 寄存器并再次移出真的会更快吗?

案例二

相反,您使用的是较少基于 OO 的代码库。而不是 Point3D 对象的数组/向量,您只需拥有一个大的浮点数组:

float coordinateData[NUM_POINTS*3];

void add(int i,int j) //yes it's unsafe, no overlap check... example only
{
  for (int x=0;x<3;++x)
  {
    coordinateData[i*3+x] += coordinateData[j*3+x];
  }
}

在这里使用 SSE 怎么样?好点?

综上所述

尝试使用 SSE 优化单向量操作实际上是否值得,还是仅在进行批量操作时才有价值?

4

4 回答 4

6

通常,您需要采取额外的步骤来充分利用 SSE(或任何其他 SIMD 架构):

  • 数据需要 16 字节对齐(理想情况下)

  • 数据需要是连续的

  • 您需要足够的数据才能使 SIMD 操作有价值

  • 您需要合并尽可能多的操作以降低加载/存储的成本

  • 您需要了解缓存/内存层次结构及其对性能的影响(例如使用条带挖掘/平铺)

于 2010-04-12T16:39:44.493 回答
1

如果您的情况是您对数据范围进行大量相同的计算,那么这很有价值。例如,您计算多对多方程的平方根。您可以在 sse 寄存器中加载 4 个值并调用一次操作。这将使性能提高 4。

并且有些库里面有所有 sse 优化。不要重新发明自行车。

于 2010-04-12T16:25:33.210 回答
1

这篇Gamasutra 文章展示了如何制作基于 SSE 的快速代码。它详细介绍了您的“案例 1”。

源代码可从作者主页获得。

于 2010-07-29T09:15:35.157 回答
0

几年前我在工作中尝试了案例一,性能提升几乎无法衡量。最后我决定跳过它,因为在 16 字节边界上对齐所有的麻烦Point3D 使它不值得。

正如您正确猜到的那样,SSE 最适合批量操作,它们可以提供相当不错的加速。在继续使用 SSE 内在函数之前,请检查编译器已经生成了哪些代码。我从经验中知道,例如 Visual Studio 非常擅长使用 SSE 优化。

于 2010-04-12T16:53:32.087 回答