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

2024-03-13

如果您在 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?

EDIT:

这是一个例子来展示我正在谈论的内容。尽管 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?


The MSDN 页面在这里 http://msdn.microsoft.com/en-us/library/83ythb65.aspx包括以下有关您的问题“为什么不为 x64 设置默认对齐方式 8?”的相关信息:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐