什么是堆栈对齐?
为什么使用它?
可以通过编译器设置控制它吗?
这个问题的细节来自尝试将ffmpeg库与msvc一起使用时遇到的问题,但是我真正感兴趣的是对“堆栈对齐”的解释。
细节:
出现以下错误:“编译器未对齐堆栈变量。Libavcodec具有
被错误编译”,然后在avcodec.dll中崩溃。
谢谢,
担
最佳答案
内存中变量的对齐(历史很短)。
过去,计算机具有8位数据总线。这意味着,每个时钟周期可以处理8位信息。那很好。
然后是16位计算机。由于向下兼容性和其他问题,保留了8位字节,并引入了16位字。每个字是2个字节。并且每个时钟周期可以处理16位信息。但这提出了一个小问题。
让我们看一下内存映射:
+----+
|0000|
|0001|
+----+
|0002|
|0003|
+----+
|0004|
|0005|
+----+
| .. |
每个地址都有一个字节,可以单独访问。
但是单词只能在偶数地址处获取。因此,如果我们在0000处读取一个字,则会在0000和0001处读取字节。但是,如果要在位置0001处读取该字,则需要两次读取访问。首先是0000,0001,然后是0002,0003,而我们仅保留0001,0002。
当然,这花费了一些额外的时间,对此不胜感激。因此,这就是他们发明对齐技术的原因。因此,我们将字变量存储在字边界,将字节变量存储在字节边界。
例如,如果我们有一个带有字节字段(B)和字字段(W)的结构(以及一个非常幼稚的编译器),则会得到以下内容:
+----+
|0000| B
|0001| W
+----+
|0002| W
|0003|
+----+
这不好玩。但是当使用单词对齐时,我们发现:
+----+
|0000| B
|0001| -
+----+
|0002| W
|0003| W
+----+
在此牺牲内存来提高访问速度。
您可以想象,当使用双字(4个字节)或四字(8个字节)时,这甚至更为重要。这就是为什么对于大多数现代编译器,您可以在编译程序时选择要使用的对齐方式。