为什么32位和64位程序的结构大小不同?

时间:2015-01-08 06:30:12

标签: c++ c

以下是一个简单的C程序:

#include <stdio.h>

typedef struct
{
    char a;
    double b;
} A;
int main(void) {
    printf("sizeof(A) is %d bytes\n", sizeof(A));
    return 0;
}

当我将其编译成32-bit程序时,输出为:

sizeof(A) is 12 bytes

我知道结构内存模块应该是:

 ____________________________
|a|3 padding| b              |
 ————————————————————————————

但是当我把它编译成64-bit程序时,输出是:

sizeof(A) is 16 bytes

所以结构内存模块应该是:

 ____________________________________
|a|7 padding        | b              |
 ____________________________________

就个人而言,我认为无论该计划是32-bit还是64-bit,结构的大小应始终为16字节(因为char1字节长,double的对齐是8字节)。为什么12程序中的大小为32-bit个字节?

3 个答案:

答案 0 :(得分:2)

在32位和64位计算机上的Intel CPU上,“ SIMD”变体的浮点指令在单个计算机上读/写16个字节(2个双精度)或8个字节(一个双精度)。指令。这些是处理浮点的最常见说明。一切都取决于速度:

可以通过“对齐的读取指令”或“未对齐的读取指令”来读取单个数据项。确保对齐的版本更快。未对齐的指令必须处理复杂的情况,其中数据在两条高速缓存行甚至两个不同的内存页之间分配。 此外,CPU针对某些指令(即对齐的指令)进行了优化。 如此优化,以至于读取1字节的数据比读取16个对齐的字节要花费更多的时间。 8088(MOV AL / MOV AH等)的原始1字节指令未经过硬件优化。

编译器编写者必须选择密集代码或快速代码。在过去,当我的PC拥有16 KB的内存时,内存很少。后来,人们可以指示编译器准确地对齐结构成员。当64位CPU出现时,内存足够便宜,以至于结构的大小变成16字节的倍数,并且每个结构成员都按照其自然边界对齐-根据其类型:短裤的偶数地址,mod(4,0)对于int和float,对于_int64为mod(8,0),对于_mm128为double(mod)(16,0),对于_mm256为mod(32,0)

答案 1 :(得分:1)

这是实施定义。

最后,它取决于访问内存时CPU指令的限制。编译器通常会尝试选择速度最快的布局,然后选择内存使用率第二。

答案 2 :(得分:1)

在深入研究这个问题之后,我想自己回答问题。

我的操作系统是Solaris,这个问题出现在X86上(Jonathan Leffler的评论是正确的)。当我在SPARC上测试它时,32位和64位程序输出&#34; sizeof(A) is 16 bytes&#34;。

我认为原因是:

(1)在X86上,访问非对齐数据不会导致程序失效,只会影响性能。对于32-bit程序,CPU指令一次可以访问4-byte内存,因此访问8-byte double将使用2指令,无需对齐数据。但是对于64-bit程序,CPU指令一次可以访问8-byte内存,因此对齐8-byte double将仅使用1指令来获取数据,这将改善性能。

(2)Ox SPARC,数据需要严格对齐,否则将导致&#34; Bus error&#34;。因此,在7数据之前始终有double个填充字节,以使其在8-byte地址上对齐。

简单来说,此问题取决于CPU,因为user694733已经回答。