仰望—星空 2023-11-25 13:38 采纳率: 93.3%
浏览 6
已结题

Direct3D在类中为什么要使用XMFLOATn而非XMVECTOR?

微软官方建议:在类内部使用XMFLOATn来存储和表示向量。
理由是:XMVECTOR即__m128类型需要按16字节对齐,这对于全局变量和局部变量是自动实现的,而类内属性却不是。
根据C++默认内存对齐规则,结构体内部会自动实现内存对齐,即结构体中每个属性所处内存的偏移量等于其大小的整数倍。
我查看了__m128的定义,发现其使用 " align(16) " 来表明其所占字节为16的整数倍,那么为什么类内的__m128属性不会实现内存对齐?
我查阅相关资料,有一个帖子说:“该类不是在对齐地址处创建的,因此即使 XM* 成员在 16 字节边界上对齐,父级的对齐方式也会错位它们,从而导致崩溃”。
如果类中的属性会因为类的起始地址导致错位,那么像常见的结构体,怎样保证只要 “结构体中属性内存的偏移量等于其大小的整数倍” 就有 “结构体中属性内存的起始地址是其大小的整数倍”。

  • 写回答

2条回答 默认 最新

  • K_n_i_g_h_t_1990 2023-11-25 13:57
    关注

    在C++中,类内部的内存对齐和结构体的内存对齐规则是有区别的。在类内部,如果类中包含有向量类型(如__m128)这样需要特殊对齐的成员,需要手动进行对齐处理。

    在默认情况下,C++类的内存对齐是根据其中包含的成员的最大对齐要求来决定的。因此,如果类内有成员的对齐要求超过默认对齐(通常是4或8字节),就需要手动设置对齐方式。

    对于结构体,如果结构体中的成员有特殊的对齐要求,整个结构体的对齐方式通常会被设置为其中最大的成员对齐要求。这意味着结构体中每个成员的内存偏移量等于其大小的整数倍,但整个结构体的起始地址不一定是其大小的整数倍。

    以下是一个例子,展示了如何使用 alignas 关键字来手动设置类内部和结构体的对齐方式:

    #include <iostream>
    #include <immintrin.h>
    
    class MyClass {
    public:
        alignas(16) __m128 vector; // 使用 alignas(16) 来设置对齐方式
        int integer;
        // 其他成员...
    };
    
    struct MyStruct {
        alignas(16) int integer; // 使用 alignas(16) 来设置对齐方式
        float floatingPoint;
        // 其他成员...
    };
    
    int main() {
        std::cout << "Size of MyClass: " << sizeof(MyClass) << std::endl;
        std::cout << "Size of MyStruct: " << sizeof(MyStruct) << std::endl;
    
        return 0;
    }
    

    在上述代码中,alignas(16) 用于指定 __m128int 的对齐方式为16字节。这样就能确保类或结构体中的成员按照期望的对齐方式排列,避免了在类内部或结构体中因为对齐问题而导致的错误。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 12月3日
  • 已采纳回答 11月25日
  • 创建了问题 11月25日

悬赏问题

  • ¥15 Qt安装后运行不了,这是我电脑的问题吗
  • ¥15 数据量少可以用MK趋势分析吗
  • ¥15 使用VH6501干扰RTR位,CANoe上显示的错误帧不足32个就进入bus off快慢恢复,为什么?
  • ¥15 大智慧怎么编写一个选股程序
  • ¥100 python 调用 cgps 命令获取 实时位置信息
  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上
  • ¥50 有没有适合匹配类似图中的运动规律的图像处理算法