【问题标题】:C++ Align by structure size or largest alignment requirement among its members?C ++按结构大小或成员之间的最大对齐要求对齐?
【发布时间】:2011-11-06 17:19:50
【问题描述】:

以这个结构为例:

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 字节对齐的,我可能会浪费不会浪费的空间。

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

【问题讨论】:

  • 您是否正在尝试编写可在多个编译器上运行的可移植代码?
  • should store this function,存储什么?
  • __pad 是一个反向标识符。
  • 也是保留标识符
  • 哦该死的 :) 是的,保罗说的。

标签: c++ memory


【解决方案1】:

如果您想在任何英特尔 CPU 上调整性能,您应该遵循英特尔优化手册中的以下指南:

为获得最佳性能,请按如下方式对齐数据:

• 在任意地址对齐 8 位数据。

• 对齐 16 位数据以包含在对齐的 4 字节字中。

• 对齐 32 位数据,使其基地址为 4 的倍数。

• 对齐 64 位数据,使其基地址为 8 的倍数。

• 对齐 80 位数据,使其基地址为 16 的倍数。

• 对齐 128 位数据,使其基地址为 16 的倍数。

所以在您的情况下,您将对齐 16,而不是 4 或 8,因为您的结构长度介于 64 和 128 位之间,16 是最佳上拟合,它还可以启用其他一些额外的东西,比如能够使用 SIMD 复制结构。

【讨论】:

  • 这里有一个误会。该结构没有被完全访问。它的成员被访问。这个结构只需要在 32 位边界上对齐。
  • @David: 不,那是为了访问结构 members
  • 访问成员是你可以用结构做的所有事情!祈祷告诉,你会用 1000 位结构做什么?
  • @David:您可以复制它,流式传输到 GPU 等。还需要考虑缓存行之类的东西
  • 嗯。最严重的惩罚是针对成员的未对齐读/写/操作,但在 x86 上没有那么多。在缓存方面,对齐和空间之间也有平衡。对这个结构使用 16 字节对齐而不是 12 字节会导致 25% 的缓存未命中。我不介意打赌某些算法使用 12 字节对齐会更好,而其他算法使用 16 字节对齐会更好。
【解决方案2】:

结构的最佳对齐等于结构的任何成员的最大对齐。在本例中为 4。

更新

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

【讨论】:

  • 对齐结构元素可优化访问速度。包装结构元素针对尺寸进行了优化。
  • 正确对齐结构可以优化以避免未定义的行为,从而在您最不期望的时候巧妙地破坏您的代码。
  • 我不是在谈论结构成员的对齐,而是结构本身。我应该将结构存储在 sizeof(Packing) 或 sizeof(int) 的倍数中,这是最大的成员吗?
  • 我知道你在说什么。我的回答已经回答了此评论中的问题。
  • @tiago 我认为您的陈述总体上可能是正确的,尽管我确信您可以在某些平台上找到某些操作的例外情况!
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-23
    • 2016-09-18
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多