NOTE

3.6 内存对齐

1. 机器字长 1.1. 地址总线和数据总线 - CPU通过地址总线到内存中寻址,而内存通过数据总线把数据传输给CPU - 地址总线的位数决定了内存大小:比如8bit地址总线,那么可以寻址[0, 255]总共256B的内存,内存超过256B也利用不了 - 数据总线则决定了一次性能传输多少数据:比如要

Go创建于 更新于 historical

这是历史学习笔记,可能存在过时或不完整的理解。

1. 机器字长

1.1. 地址总线和数据总线

  • CPU通过地址总线到内存中寻址,而内存通过数据总线把数据传输给CPU
  • 地址总线的位数决定了内存大小:比如8bit地址总线,那么可以寻址[0, 255]总共256B的内存,内存超过256B也利用不了
  • 数据总线则决定了一次性能传输多少数据:比如要想一次性操作1B,那么需要8bit数据总线
    • 这个也叫做机器字长

2. 内存寻址

  • 内存条

3. 内存对齐是什么

为保证程序的高效运行,编译器会把各种类型的数据安排到合适的地址,并占用合适的长度 内存地址要求数据存储地址以及占用的字节数都要是对其边界的整数倍

4. 如何确定对齐边界

  • 类型大小
  • 平台最大对齐边界
  • 对齐边界就取上面两者的较小值
    • 这是为了兼顾性能和内存

4.1. 结构体的对齐边界

5. 为什么需要内存对齐

5.1. 平台原因

不是所有的硬件平台都可以访问任意地址的任意数据

5.2. 性能原因

为了访问未对齐的内存,处理器需要发起两次内存访问;对齐的则只需要一次内存访问

6. 怎么使用内存对齐

6.1. 数据结构对齐

依赖于类型的大小保证和对齐保证

  • 大小保证

  • 对齐保证

6.1.1. 工具

  • layout

  • optmize

6.1.2. 举例

  • struct内字段如果填充过多,可以重排使得字段排列更加紧密,减少内存浪费
  • 零大小字段要避免作为struct最后一个字段,会有内存浪费

6.2. 内存地址对齐

变量的地址该变量类型的对齐值的整数倍

uintprt(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0

6.2.1. 举例

7. 参考