三维矢量的SSE对齐

SSE alignment of 3D vector

本文关键字:SSE 对齐 三维      更新时间:2023-10-16

我希望确保SSE用于我的3D(96位)浮点矢量的算术。然而,我读到了关于什么是必要的相互矛盾的观点。

有些文章/帖子说我需要使用4D向量并"忽略"第4个元素,有些文章/文章说我必须用__declspec(align(16))之类的东西来装饰我的类并覆盖new运算符,还有一些文章/帖子认为编译器足够聪明,可以为我对齐东西(我真的希望这是真的!)。

我正在使用Eigen库,但发现"不受支持"的AlignedVector3类不适合使用(例如,在进行分量除法时除以零错误,lpNorm函数包括伪第四元素)。

我读过的很多文章都已经好几年了,所以我希望现代编译器/SSE版本/CPU可以为我对齐数据,或者使用非16字节对齐的数据。任何关于这方面的最新知识都将不胜感激!

实际上我们在工作中使用SIMD,也许我可以向您提供我的反馈。对齐是处理SIMD时必须注意的问题,这是为了确保缓存线对齐。然而,我不确定如果它没有对齐,它是否仍然会导致崩溃,或者CPU是否能够进行管理(就像以前的未对齐标量类型一样,它会导致崩溃。现在CPU会处理它,但它会降低性能)。也许你可以看看这里SSE,内部和对齐它似乎对问题的对齐部分有很好的答案。

事实上,即使它在物理上是4D向量,您也将其用作3D向量,这并不是一个真正好的做法,因为您无法从SIMD指令的所有性能中获益。匹配它的最佳方式是使用阵列结构(SOA)。

注意:我假设128位SIMD寄存器映射到4种标量类型(int或float)

例如,如果您有4个三维点(或向量),按照您的方式,您将有4个4D向量,忽略每个点的第4个分量。总的来说,您最终会获得4*4个可访问的值。

通过使用SOA,您将拥有3个SIMD128位(12个值)寄存器,并将以以下方式存储您的点。SIMD-

  • r1:x x x
  • r2:y y y
  • r3:z z z z

通过这种方式,您可以填充整个SIMD寄存器,从而最大限度地利用SIMD优势。另一件事是,您必须进行的许多计算(例如添加2组4个向量)将只需要3条SIMD指令。它的使用和理解有点棘手,但当你这样做时,收获是巨大的。

当然,你不可能在所有情况下都以这种方式使用它,所以你会回到忽略最后一个值的原始解决方案。