c++ - 3D vector 的 SSE 对齐

标签 c++ memory vector 3d sse

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

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

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

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

最佳答案

实际上,我们在工作中使用 SIMD,或许我可以就此向您提供反馈。 对齐是处理 SIMD 时必须注意的事情,这是为了确保缓存行对齐。 但是我不确定如果它没有对齐或者 CPU 是否能够管理它是否仍然会导致崩溃(就像过去没有对齐的标量类型,它导致崩溃,现在 CPU 处理它但它变慢了表演)。 也许你可以看这里SSE, intrinsics, and alignment 它似乎对问题的对齐部分有很好的答案。

事实上您将它用作 3D vector ,即使它在物理上是一个 4D vector ,这并不是一个很好的做法,因为您没有从 SIMD 指令的所有性能中获益。它匹配的最佳方式是使用数组结构 (SOA)。

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

例如,如果您有 4 个 3D 点(或 vector ),按照您的方式,您将有 4 个 4D vector ,忽略每个点的第 4 个分量。 总共您最终得到 4 * 4 个可访问的值。

通过使用 SOA,您将拥有 3 个 SIMD 128 位(12 个值)寄存器,您将按以下方式存储您的点。 单片机

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

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

当然,您无法在所有情况下都以这种方式使用它,因此您将退回到忽略最后一个值的原始解决方案。

关于c++ - 3D vector 的 SSE 对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37369413/

相关文章:

c++ - "#include <QtCore/QCoreApplication>"与 "#include <QCoreApplication>"

c++ - cpp中的模板

c++ - 何时使用命名空间或结构?

c++ - 具有持久查找的线性内存容器?

c++ - 通过迭代器从 std::vector 中移除

c++ - 从类型列表创建 vector 元组

c++ - operator [] 在 vector 类上重载

memory - 当包含它的变量被重新分配时,分配会发生什么?

memory - 平板系统和伙伴系统有什么区别?

c++ - 使用 vector 模板时出现 mingw 链接器错误