首页 / GO / Go | 结构体与内存对齐
Go | 结构体与内存对齐
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Go | 结构体与内存对齐,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3095字,纯文字阅读大概需要5分钟。
内容图文
CPU 要想从内存读取数据,需要通过地址总线,把地址传输给内存,内存准备好数据,输出到数据总线,交给CPU。
如果地址总线只有8根[0,255],那这个地址就只有8位,可以表示256个地址,因为表示不了更多的地址,就用不到更大的内存,所以256byte就是8根地址总线最大的寻址空间,要使用更大的空间,就要有更宽的地址总线。
例如:32位地址总线[0,2^32-1],就可以寻址4G内存了
每次操作1字节太慢,那就加宽数据总线,要想每次操作4字节,就要有至少32位数据总线,8字节就要64位数据总线。
这里每次操作的字节数,就是所谓的机器字长
内存布局
通过8个bank就可以选择行选择列来定位一个地址,这不像我们逻辑上认为的,那样连续的存在,但他们公用同一个地址。
各自选择同一个位置的一个字节,再组合起来作为我们逻辑上认为的连续8个字节,通过这样的并行计算,提高了内存访问的效率,但是用这种设计,addrss就只能是8的倍数。
如果非要错开一个格儿,由于最后一个字节对应的位置与前七个不同,不能在一次操作中被同一个地址选中,所以这样的地址是不能用的。硬件不支持
之所有些CPU能够支持访问任意地址,是因为它做了许多处理
例如你想从地址1开始读八个字节的数据。
CPU会分两次读,第一次从0-7,但只取后七字节,第二次从8-15,但只取第一个字节,再把两次结果拼接起来拿到所需数据,但这必然会影响性能。
所以保证程序顺利高效的运行,编译器会把各种类型的数据安排到合适的地址,并占用合适的长度,这就是内存对齐。
每种类型的对齐值就是它的对齐边界,内存对齐要求数据存储地址,以及占用的字节数都要是它对齐边界的倍数。
这个int32要错开两个字节,从4开始,却不能紧接着从2开始
如何确定对齐边界呢
这和平台有关,Go语言支持这些平台。
可以看到常见的32位平台,指针宽度和寄存器宽度都是4字节。64位平台上都是8字节,而被Go语言称为寄存器宽度的这个值,就可以理解为机器字长,也是平台对应的最大对齐边界
数据类型的对齐边界,是取类型大小与平台最大对齐边界中较小的那个。不过要注意同一个类型在不同平台上,大小可能不同,对齐边界也可能不同
内存边界这样选择,依然是为了减少浪费,提高性能
为什么不统一使用平台最大对齐边界,或者统一按照类型大小来对齐
假设目前是64位平台,最大对齐边界为8字节。
int8只有一个字节,按照一字节对齐的话,他可以放在任何位置,因为总能通过一次读取把它完整拿出来。如果统一对齐到8字节,虽然同样只要读取一次,但是每个int8类型的变量都要浪费7个字节,所以对齐到1。
int16占两字节,按照两字节对齐,可以从0、2、4、6、8、10…而且能保证只用读取一次,如果按照一字节对齐,就可能存成[7-8],那就要读取两次再截取拼接,很影响性能。
如果对齐到8字节,会向int8一样,会浪费内存
假设目前是32位平台,最大对齐边界为4字节。
int64占8字节,如果在前两个字节被占用的情况下,如果对齐到类型大小8,就要从8位置开始存,如果对齐到4,就可以从4位置开始存,内存浪费更少。
结构体的对齐边界
对结构体而言,首先要确定每个成员的对齐边界,然后取其中最大的,这就是这个结构体类型的对齐边界。
内存对齐要求:
- 存储这个结构体的起始地址是对齐边界的倍数,假设起始地址为0.
- 结构体的每个成员在存储时,都要把这个起始地址当作地址0,然后再用相对地址来决定自己该放在哪儿。
- 结构体整体占用字节数需要是类型对齐边界的倍数,不够的话要往后扩张一下。
结构体整体占用字节数需要是类型对齐边界的倍数(22%8!=0),不够的话要往后扩张一下吗,所以他要扩充到相对地址32这里(24%8==0),最终这个结构体类型的大小就是24字节。
为什么要限制类型大小等于对齐边界的整数倍?
此时第二个元素并没有内存对齐。
所以只有每个结构体的大小都是对齐值的整数倍,才能保证数组中每一个都是内存对齐。
内容总结
以上是互联网集市为您收集整理的Go | 结构体与内存对齐全部内容,希望文章能够帮你解决Go | 结构体与内存对齐所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。