Go内存对齐
Go内存对齐…
为什么要内存对齐?
平台(移植性)原因:不是所有的硬件平台都能够访问任意地址上的任意数据。例如:特定的硬件平台只允许在特定地址获取特定类型的数据,否则会导致异常情况
性能原因:若访问未对齐的内存,将会导致 CPU 进行两次内存访问,并且要花费额外的时钟周期来处理对齐及运算。而本身就对齐的内存仅需要一次访问就可以完成读取动作
成员对齐
1 |
|
输出结果:
1 |
|
在 Go 中可以调用 unsafe.Alignof
来返回相应类型的对齐系数。通过观察输出结果,可得知基本都是 2^n
,最大也不会超过
8。这是因为我手提(64 位)编译器默认对齐系数是 8,因此最大值不会超过这个数
整体对齐
在上小节中,提到了结构体中的成员变量要做字节对齐。那么想当然身为最终结果的结构体,也是需要做字节对齐的
对齐规则
结构体的成员变量,第一个成员变量的偏移量为 0。往后的每个成员变量的对齐值必须为编译器默认对齐长度(
#pragma pack(n)
)或
当前成员变量类型的长度(unsafe.Sizeof
),取最小值作为当前类型的对齐值。其偏移量必须为对齐值的整数倍结构体本身,对齐值必须为编译器默认对齐长度(
#pragma pack(n)
)或结构体的所有成员变量类型中的最大长度,取*
*最大数的最小整数倍**作为对齐值
结合以上两点,可得知若编译器默认对齐长度(#pragma pack(n)
)超过结构体内成员变量的类型最大长度时,默认对齐长度是没有任何意义的
Go内存对齐
https://zhyyao.me/2021/02/03/technology/golang/memory_to_its/