16 字节对齐问题

16 byte alignment issue

本文关键字:问题 对齐 字节      更新时间:2023-10-16

我正在使用DirectXMath,在类中创建XMMatrixXMVector

当我调用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_ .简单。慢。现在可以工作,只需一行代码。;)
  • 不要将XMVECTORXMMATRIX存储在堆上。存储XMFLOAT4XMFLOAT4X4,并仅在需要时转换为 SIMD 类型(因此它们将存储在堆栈中)。慢。许多代码要更改(可能)。
  • 不要将XMVECTORXMMATRIX存储在堆上,第 2 部分。只需将您的类存储在堆栈上即可。快。挺难的。许多代码要更改(可能)。
  • 使用对齐的分配器。快。硬。很多小时要谷歌,很多代码要编写和调试。
  • 不要使用 DirectXMath(以前称为 XMMath)库。选择任何其他(有很多)或编写自己的。快。许多代码要更改(可能)。

如果你想要对齐的分配器,它与DirectX或DirectXMath无关。这是高级主题。没有人能给你完整的解决方案。但是,以下是谷歌搜索的一些结果:

  • 返回与新的对齐的内存?
  • 更难C++:对齐的内存分配
  • 更多

要非常细心。使用错误的内存分配器,您可以引入比解决更多的问题。

希望它以某种方式有所帮助。祝您编码愉快!:)