代码之家  ›  专栏  ›  技术社区  ›  Dave

3D矢量的SSE对齐

  •  1
  • Dave  · 技术社区  · 8 年前

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

    有些文章/帖子说我需要使用4D向量并“忽略”第四个元素,有些文章/贴子说我必须用类似这样的东西来装饰我的类 __declspec(align(16)) 并覆盖 new 有人说编译器足够聪明,可以为我对齐内容(我真的希望这是真的!)。

    我正在使用Eigen库,但发现“不支持” AlignedVector3 类不符合目的(例如,在进行组件除法时出现零除法错误, lpNorm 函数包括虚拟的第4个元素)。

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

    1 回复  |  直到 8 年前
        1
  •  2
  •   Community CDub    7 年前

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

    因为您将它用作3D矢量,即使它实际上是一个4D矢量,这并不是一个真正好的实践,因为您不能从SIMD指令的所有性能中获益。最好的匹配方法是使用数组结构(SOA)。

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

    例如,如果您有4个3D点(或矢量),那么您将有4个4D矢量,忽略每个点的第4个分量。 总的来说,您最终可以访问4*4个值。

    通过使用SOA,您将拥有3个SIMD 128位(12个值)寄存器,并将按以下方式存储点。 模拟指令集

    • r1:x x x x
    • r2:是的是的
    • r3:z z z z

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

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