【问题标题】:Why do x64 projects use a default packing alignment of 16?为什么 x64 项目使用 16 的默认打包对齐方式?
【发布时间】:2013-04-15 14:38:51
【问题描述】:

如果你在 VS2012 的 x64 项目中编译以下代码,没有任何 /Zp 标志:

#pragma pack(show)

然后编译器会吐出来:

value of pragma pack(show) == 16

如果项目使用Win32的话,编译器会吐槽:

value of pragma pack(show) == 8

我不明白的是,Win64 中任何类型(即:long long 和指针)的最大自然对齐方式是 8。那么为什么不将 x64 的默认对齐方式设为 8?

有点相关,为什么有人会使用 /Zp16?

编辑:

这里有一个例子来说明我在说什么。尽管对于 x64,指针具有 8 字节的自然对齐,但 Zp1 可以强制它们到 1 字节的边界。

struct A
{
    char a;
    char* b;
}

// Zp16
// Offset of a == 0
// Offset of b == 8

// Zp1
// Offset of a == 0
// Offset of b == 1

现在如果我们举一个使用 SSE 的例子:

struct A
{
    char a;
    char* b;
    __m128 c; // uses declspec(align(16)) in xmmintrinsic.h
}

// Zp16
// Offset of a == 0
// Offset of b == 8
// Offset of c == 16

// Zp1
// Offset of a == 0
// Offset of b == 1
// Offset of c == 16

如果 __m128 确实是内置类型,那么我希望 Zp1 的偏移量为 9。但由于它在 xmmintrinsic.h 中的定义中使用了 __declspec(align(16)),这胜过任何 Zp 设置。

所以我的问题的措辞有点不同:'c' 的类型是否自然对齐为 16B,但在前面的示例中偏移量为 9?

【问题讨论】:

    标签: windows visual-studio-2012 64-bit


    【解决方案1】:

    MSDN page here 包含以下有关您的问题“为什么不为 x64 设置默认对齐 8?”的相关信息:

    编写使用最新处理器指令的应用程序会引入一些新的限制和问题。特别是,许多新指令要求数据必须与 16 字节边界对齐。此外,通过将常用数据与特定处理器的高速缓存行大小对齐,可以提高高速缓存性能。例如,如果您定义一个大小小于 32 字节的结构,您可能希望将其对齐为 32 字节,以确保有效缓存该结构类型的对象。

    【讨论】:

    • 公平点,我真的不是低级别的专家,只是在评论中发表太多。无论如何,我认为它可能会提供信息,但我知道这不是答案,抱歉。
    • 这个答案是正确的。 64 位代码生成器喜欢使用 SSE2 指令。它们有 16 字节的对齐要求。特别是在 VS2012 中,它添加了自动矢量化。这个答案不应该被否决。
    • @HansPassant,我用一个例子编辑了这个问题。顺便说一句,我对答案投了反对票,因为他承认不知道他在说什么。我也觉得很模糊。话虽如此,您的回答更接近我的预期。
    【解决方案2】:

    为什么 x64 项目使用 16 的默认打包对齐方式?

    在 x64 上,浮点是在 SSE 单元中执行的。你说最大的类型有对齐 8。但这是不正确的。某些 SSE 内在类型(例如 __m128)的对齐方式为 16。

    【讨论】:

    • ...通过 __declspec(align(16))。 __declspec(align) 覆盖 Zp 和“#pragma pack”。由于它使用 __declspec(align),因此您不能像使用指针或 int 或其他任何东西一样通过 /Zp 更改其对齐方式。
    • 补充一点:因为它使用 __declspec(align(16)),所以默认 16 字节对齐是没有意义的。它可以是 8 字节,但 declspec 仍会强制它为 16。
    • 我回答了这个问题。我引用了问题中的一句话来表明我在回答什么。
    • 你回答了一个问题,但不是我的。
    • 哦,我以为你写了问题标题。
    猜你喜欢
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 2011-02-17
    • 2013-07-22
    • 2011-12-10
    • 2019-03-21
    相关资源
    最近更新 更多