三维矢量的SSE对齐
SSE alignment of 3D vector
我希望确保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指令。它的使用和理解有点棘手,但当你这样做时,收获是巨大的。
当然,你不可能在所有情况下都以这种方式使用它,所以你会回到忽略最后一个值的原始解决方案。
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 64位机器上的C++内存对齐
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 使 std::vector 分配对齐内存的现代方法
- C++ cout 将双精度对齐到精度 2 并正确对齐
- 在 64 位边界上对齐C++结构数组?
- 三维矢量的SSE对齐
- 像“float[10][10]”初始化的数组是否已经针对 SIMD/SSE 进行了内存对齐
- SSE 向量的对齐和未对齐加载和存储 - 如何减少代码重复
- 存储SSE操作结果时的对齐要求
- 对齐、总尺寸和SSE
- 动态分配的内存在 SSE 中未对齐
- 使用带有自定义对齐分配器实现的最新g++,使用SSE和-O3选项编译时出现非法指令(核心转储)
- 正在对齐SSE的模板矢量结构
- 如何对齐结构数组,每个结构都需要对齐(SSE)
- 在托管代码中调用SSE代码(对齐)
- C++中SSE的内存对齐,_aligned_malloc等效
- 随机存取与SSE对齐的存储器