0

我对对齐要求和字长感到困惑。我正在使用 64 位处理器,所以字长是 8,这意味着分配的地址应该是 8 的倍数,对吧?
alignof给了我意想不到的结果。

struct A
{
    int a;
    char b;
}

输出:

sizeof(A): 8
alignof(A): 4 // why?

相比下,

sizeof(double): 8
alignof(double): 8

如果我碰巧提供的地址是 4 的倍数但不是 8 的倍数A,性能会因为多了一次访问而降低,对吗?

是因为alignof()提供了我们需要遵循的最少要求,而在这个特定示例中对齐 8 个字节更好地与简单的内存性能权衡?

4

3 回答 3

1

该标准对对齐和一般结构布局几乎没有保证。

其中:

  • 所有对齐都是 2 的幂。
  • 一个结构的对齐要求不小于其最对齐的子对象。(琐碎的)
  • 结构的大小是其对齐方式的倍数(也是微不足道的,否则数组是不可能的)

你的例子满足了所有这些。如果你愿意,你可以得到更强的对齐(C++11):

struct alignas(8) A {
    int a;
    char b;
}

此外,仅仅因为处理器的位数是 64,这并没有反映在大多数类型的更高对齐要求中,尽管更强对齐的数据可以具有更好的读/写性能。

如果较弱的对齐方式意味着数据跨越更多缓存行并且处理器必须因此获取更多缓存行,那么您只会获得更差的性能。

于 2014-08-09T18:39:14.573 回答
1

对齐要求是特定于平台的,但通常原始类型的最小对齐与其大小相同。处理器可以在任何 32 位边界上执行 32 位加载/存储操作,但 64 位加载或存储需要 64 位对齐。

您的结构的对齐方式为 4,因为其中没有任何内容需要 8 字节对齐。虽然它只包含 5 个字节的有意义的数据,但它的大小被填充为 8,以便在数组中,第二个和后续实例也将正确对齐。

于 2014-08-09T22:56:10.207 回答
1

一些硬件系统禁止未对齐的内存访问。这样做会导致异常。这在 RISC 处理器中很常见。

其他处理器会受到性能影响。访问未对齐的数据通常需要两个处理器周期。

上述结果的原因是您的编译器使用的是 4 字节 int(不是 8 字节)。

struct A
{
    int a;     // 4 bytes
    char b;    // 1 byte
    // 3 bytes padding
}
于 2014-08-12T03:23:49.627 回答