首页 文章

C根据结构大小或其成员之间的最大对齐要求进行对齐?

提问于
浏览
3

以此结构为例:

struct Packing
{
     int x; // 4-byte align
     int y; // 4-byte align
     short int z; // 2-byte align
     char m; // 1-byte align;
     char _pad[1]; // explicit padding
};

此结构的大小为12个字节 .

那么应该将此结构存储在结构大小(12字节)的倍数或sizeof(int)的倍数中(结构成员中最大的对齐要求)?

由于12的倍数也是4的倍数(sizeof(int)),我猜结构将在12的地址倍数中正确对齐,但如果是4字节对齐,我可能会浪费不会浪费的空间 .

EDIT: 在地址0x00000012处,结构将被对齐,其第一个成员也将对齐,因为12是4的倍数 . 如果将其存储在地址0x00000004,会怎样?在这种情况下,结构的第一个元素将是对齐的,但结构本身呢?

3 回答

  • 3

    结构的最佳对齐方式等于任何结构成员的最大对齐方式 . 在这种情况下是4 .

    Update

    以上假设您对结构执行的主要操作是访问其成员 . 有关更多讨论,请参阅Necrolis's answer的评论 . 简而言之,我怀疑你的问题的真正答案在很大程度上取决于所涉及的硬件和你正在使用的算法 .

  • 0

    如果您想在任何英特尔CPU上调整性能,您应该遵循英特尔优化手册中的这些指导原则:

    为获得最佳性能,请按如下方式对齐数据:•在任何地址对齐8位数据 . •将16位数据对齐,使其包含在对齐的4字节字中 . •对齐32位数据,使其基址为四的倍数 . •对齐64位数据,使其基址为8的倍数 . •对齐80位数据,使其基址为16的倍数 . •对齐128位数据,使其基址为16的倍数 .

    所以在你的情况下,你将对齐16,而不是4或8,因为你的结构长度在64到128位之间,16是最好的上部拟合,它还启用了一些其他额外的东西,比如能够使用SIMD来复制结构 .

  • 5

    允许编译器留下它想要的任何间隙,以确保它可以有效地访问结构 . 究竟需要什么取决于底层架构 . 如果您使用的是32位架构并且没有半字或字节数据加载,则编译器可能会将所有数据成员(包括z,m和_pad)与字边界对齐 . 但是,如果架构可以执行有效的半字和字节数据加载,那么您可能会发现您的struct具有预期的 sizeof(Packing) == 12

相关问题