为什么在我的实现中所有数组都对齐到 16 字节?
Why are all arrays aligned to 16 bytes on my implementation?
我非常简单的代码如下所示
#include <iostream>
#include <stdalign.h>
int main() {
char array_char[2] = {'a', 'b'};
float array_float[2] = {1, 2};
std::cout << "alignof(array_char): " << alignof(array_char) << std::endl;
std::cout << "alignof(array_float): " << alignof(array_float) << std::endl;
std::cout << "address of array_char: " << (void *) array_char << std::endl;
std::cout << "address of array_float: " << array_float << std::endl;
}
这段代码的输出是
alignof(array_char): 1
alignof(array_float): 4
address of array_char: 0x7fff5e8ec580
address of array_float: 0x7fff5e8ec570
alignof
运算结果符合预期,但两个数组的真实地址不一致。无论我试了多少次,地址总是 16 字节对齐。
我在 Ubuntu 16.04 上使用 gcc 5.4.0 和第 7 代英特尔酷睿 i5 CPU。
我找到了 this 补丁。
这似乎是 x86_64 在 GCC 6.4 中修复的错误。
System V x86-64 ABI 要求聚合类型(例如数组和 struct
s)在至少 16 字节大的情况下至少对齐 16 字节。根据 ABI 规范中的评论,这是为了方便使用 SSE 指令。
GCC 似乎将该规则错误地应用于大小为 16 位(而不是字节)和更大的聚合。
我建议您将编译器升级到更新的 GCC 版本。
但这只是一个优化问题,不是正确性问题。对变量进行更严格的对齐并没有错,并且(与提到的 SSE 一样)过度对齐在某些情况下可能会带来性能优势,这超过了浪费堆栈内存的成本。
我非常简单的代码如下所示
#include <iostream>
#include <stdalign.h>
int main() {
char array_char[2] = {'a', 'b'};
float array_float[2] = {1, 2};
std::cout << "alignof(array_char): " << alignof(array_char) << std::endl;
std::cout << "alignof(array_float): " << alignof(array_float) << std::endl;
std::cout << "address of array_char: " << (void *) array_char << std::endl;
std::cout << "address of array_float: " << array_float << std::endl;
}
这段代码的输出是
alignof(array_char): 1
alignof(array_float): 4
address of array_char: 0x7fff5e8ec580
address of array_float: 0x7fff5e8ec570
alignof
运算结果符合预期,但两个数组的真实地址不一致。无论我试了多少次,地址总是 16 字节对齐。
我在 Ubuntu 16.04 上使用 gcc 5.4.0 和第 7 代英特尔酷睿 i5 CPU。
我找到了 this 补丁。
这似乎是 x86_64 在 GCC 6.4 中修复的错误。
System V x86-64 ABI 要求聚合类型(例如数组和 struct
s)在至少 16 字节大的情况下至少对齐 16 字节。根据 ABI 规范中的评论,这是为了方便使用 SSE 指令。
GCC 似乎将该规则错误地应用于大小为 16 位(而不是字节)和更大的聚合。
我建议您将编译器升级到更新的 GCC 版本。
但这只是一个优化问题,不是正确性问题。对变量进行更严格的对齐并没有错,并且(与提到的 SSE 一样)过度对齐在某些情况下可能会带来性能优势,这超过了浪费堆栈内存的成本。