c++ - 同时将所有结构元素与标量相乘

标签 c++ vectorization sse simultaneous vector-multiplication

我有一个表示 vector 的结构。该 vector 由两个单字节整数组成。我用它们来保持 0 到 255 之间的值。

typedef uint8_T unsigned char;

struct Vector
{
  uint8_T x;
  uint8_T y;
};

现在,我程序中的主要用例是将 vector 的两个元素与一个 32 位浮点值相乘:

typedef real32_T float;

Vector Vector::operator * ( const real32_T f ) const {
  return Vector( (uint8_T)(x * f), (uint8_T)(y * f) );
};

这需要经常执行。有没有办法可以同时执行这两个乘法?也许通过矢量化、SSE 或类似方法?或者 Visual Studio 编译器是否已同时执行此操作?

另一个用例是在两个 vector 之间进行插值。

Vector Vector::interpolate(const Vector& rhs, real32_T z) const
{
  return Vector(
        (uint8_T)(x + z * (rhs.x - x)),
        (uint8_T)(y + z * (rhs.y - y))
        );
}

这已经使用了优化的插值方法(https://stackoverflow.com/a/4353537/871495)。

但是 vector 的值再次乘以相同的标量值。 是否有可能提高这些操作的性能?

谢谢

(我正在使用带有 64 位编译器的 Visual Studio 2010)

最佳答案

根据我的经验,Visual Studio(尤其是像 VS2010 这样的旧版本)本身不会做很多矢量化。他们在较新的版本中对其进行了改进,因此如果可以的话,您可能会看到编译器的更改是否可以加速您的代码。

根据使用这些函数的代码和编译器所做的优化,减慢程序速度的甚至可能不是计算。函数调用和缓存未命中可能会造成更多伤害。

您可以尝试以下方法:

  • 如果尚未完成,请在头文件中定义函数,以便编译器可以内联它们
  • 如果您在紧密循环中使用这些函数,请尝试在不调用任何函数的情况下“手动”进行计算(暂时公开变量)并查看它是否会产生速度差异)
  • 如果您有很多 vector ,请查看它们在内存中的布局方式。连续存储它们以最大限度地减少缓存未命中。
  • 要使 SSE 真正发挥作用,您必须同时处理 4 个值 - 因此将 2 个 vector 乘以 2 个 float 。在一个循环中,使用步长 2 并编写一个静态函数,使用 SSE 指令一次计算 2 个 vector 。因为您的 vector 未对齐(并且几乎不会与 8 位变量对齐),代码甚至可能比您现在的代码运行得更慢,但值得一试。
  • 如果适用并且您不依赖于从 floatuint8_t 的强制转换(例如,如果您的 float 在范围 [0,1 ]), 尝试在任何地方使用float。这可能会让编译器做更好的优化。

关于c++ - 同时将所有结构元素与标量相乘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28543755/

相关文章:

c++ - tbb::cache_aligned_allocator:使用 __m128i 获取 "request for member...which is of non-class type"。用户错误或错误?

c++ - VB DLL 中带下划线的符号是什么?

c++ - 在更改该点以下的代码后,是否很热衷于从代码中间的特定点重新运行 C++ 代码?

Python矢量化嵌套for循环

python - 使用列数组向量化 pandas 数据框列查找

matlab - 在 PLECS(分段线性电路仿真)中自行自动生成电路

c++ - 模板类和嵌套类 C++

c++ - 使用 Windows XP 和 7 将 ".txt"保存到特定目录

delphi - 使用 SSE2 在 Delphi 中内联汇编低效程序

c++ - 使用 double 运算的快速 SSE 低精度指数