结构填充 - 自然对齐的目的是什么?

时间:2014-09-01 19:35:55

标签: c caching structure padding memory-alignment

我正在学习结构填充和数据对齐。我想到了这一点,记忆中结构的所有元素应该是自然对齐的。例如,如果我声明了以下结构:

   struct align{
    char        c;
    double      d;
    int         s;
   };

如果我采用32位架构,那么它一次取4个字节。所以记住这一点,如果我开始填充,我会得到(我的假设):
1byte(char)+ 3bytes(填充)+ 8bytes(double)+ 4bytes(int)---------> 1

所有这些都应在最短的机器周期内获取。

但最初发生了以下情况:
1byte(char)+ 7bytes(填充)+ 8bytes(double)+ 4bytes(int)----------> 2

为什么我们需要这个自然对齐为double时我们可以在使用方法1时保存4位(同时在两种情况下获取具有相同机器周期数的每个元素)?

1 个答案:

答案 0 :(得分:1)

您的评论是有效的,如果您不是使用结构,而是简单地将变量作为函数内部本地堆栈的一部分放置,那么您可能会得到您正在寻找的结果。这些方面的东西:

void alignTest()
{
  char        c;
  double      d;
  int         s;
  printf("%x %x %x", (int)&c, (int)&d, (int)&s);
}

在这个例子中,编译器可以自由地在性能和内存方面做出最佳选择。哎呀,它甚至可以根据需要重新排序变量。在这个设置中,我已经使用32位编译器在4字节边界(而非8)上目睹了双倍。

另一方面,使用struct,您需要记住它是接口契约的一部分。它不仅仅是编译器选择它感觉更好的选择的问题:如果是API的一部分,这个结构将被其他程序使用,可能使用另一个编译器,或同一编译器的另一个版本。它一直在发生:想想DLL,来自其他语言的包装器(从Delphi或Python程序调用C函数)等。

您无法在"随机状态"中使用接口元素,具有不同的选择,具体取决于编译器。在这种情况下,关于结构内部变量的分配规则是由规范设置的。

在本规范中,始终遵循变量顺序,并且double在8个字节上对齐。