16 字节对齐问题
16 byte alignment issue
我正在使用DirectXMath
,在类中创建XMMatrix
和XMVector
。
当我调用XMMatrixMultiply
时,它会在其上抛出未经处理的异常。
我在网上发现这是字节诱惑的问题,因为DirectXMath
使用SIMD
指令集,导致错误对齐的堆分配。
建议的解决方案之一是使用XMFLOAT4X4
变量,然后在需要时将它们更改为临时XMMatrix
,但这不是最好和最快的解决方案imo。
另一个是使用_aligned_malloc
,但我不知道如何使用它。我从来没有做过任何内存分配,这对我来说是黑魔法。
另一个,是超载new operator
,但他们没有提供任何信息如何做到这一点。
关于重载方法,我不使用 new
来创建XMMatrix
对象,因为我不将它们用作指针。
一切都很好,直到我决定将代码拆分为类。
我认为_alligned_malloc
解决方案在这里是最好的,但我不知道如何使用它,何时何地调用它。
与可以安全存储的XMFLOAT4X4和XMFLOAT4不同,XMMATRIX和XMVECTOR是硬件寄存器(SSE,NEON等)的别名。 由于库抽象出寄存器类型和对齐要求,因此您不应尝试自己对齐类型,因为您可以轻松创建一个程序,该程序恰好在您的计算机上工作,但在另一台计算机上失败。 您应该使用安全类型进行存储(例如XMFLOAT4),或者提取抽象并直接使用矢量指令,并在应用程序中为尝试支持的每个矢量扩展提供特殊的存储和对齐代码路径。
此外,在库矢量指令上下文之外使用这些寄存器可能会因其他原因导致意外故障。 例如,如果将 XMMATRIX 存储在自己的结构中,则某些体系结构可能无法创建该结构的副本。
不假装是一个完整的答案。
有一些方法你没有提到:
-
#define _XM_NO_INTRINSICS_
.简单。慢。现在可以工作,只需一行代码。;) - 不要将
XMVECTOR
和XMMATRIX
存储在堆上。存储XMFLOAT4
或XMFLOAT4X4
,并仅在需要时转换为 SIMD 类型(因此它们将存储在堆栈中)。慢。许多代码要更改(可能)。 - 不要将
XMVECTOR
和XMMATRIX
存储在堆上,第 2 部分。只需将您的类存储在堆栈上即可。快。挺难的。许多代码要更改(可能)。 - 使用对齐的分配器。快。硬。很多小时要谷歌,很多代码要编写和调试。
- 不要使用 DirectXMath(以前称为 XMMath)库。选择任何其他(有很多)或编写自己的。快。许多代码要更改(可能)。
如果你想要对齐的分配器,它与DirectX或DirectXMath无关。这是高级主题。没有人能给你完整的解决方案。但是,以下是谷歌搜索的一些结果:
- 返回与新的对齐的内存?
- 更难C++:对齐的内存分配
- 更多
要非常细心。使用错误的内存分配器,您可以引入比解决更多的问题。
希望它以某种方式有所帮助。祝您编码愉快!:)
- 指向包含对齐 C 结构C++类的 C 指针的对齐问题
- 对齐C++字符串类型问题 std::字符串到 TStr
- 有关内存对齐的其他问题
- 多模图像对齐问题
- 正确处理字节对齐问题 - 通过UDP在16位嵌入式系统和32位桌面之间
- 在使用放置新操作符时,我真的需要担心对齐问题吗
- 如何检测/查找 64 位结构对齐问题
- MSVS 2010 C++编译器和堆栈对齐问题
- 16 字节对齐问题
- 我正试图将一个过程的结果写入一个文本文件,我遇到的问题是列的对齐问题
- 轴对齐边界框碰撞检测问题
- C++Win32在对齐按钮上的文本时出现问题
- 对齐<iomanip>问题
- 普通旧数据和“std::memcpy”对齐问题
- 结构对齐问题
- Linux上std::map的内存对齐问题
- 简单的结构对齐/填充问题
- 与PPL组合的SIMD对齐问题
- 使用char数组来容纳任意大小对象的数组,对齐问题
- 类与虚拟函数的成员对象对齐和动态分配的问题