[应用相关] 为什么要内存对齐 ?

[复制链接]
968|6
 楼主| jf101 发表于 2024-2-27 23:33 | 显示全部楼层 |阅读模式
为什么要对齐 ?


我们在上文引用的规范中有这么一段话:

This is done in order to speed up memory accesses of instances of the structure type.

翻译成中文就是 “这(指对齐操作)是为了加快结构体类型数据的内存访问速度”。

访问一个对齐的结构体中的数据会比访问一个非对齐的结构体要快!

这是因为现代大多数处理器在访问内存时,都会以一定的大小为单位,如 32 位的处理器会以 4 字节进行内存访问,64 位的处理器会以 8 字节进行内存访问。这也印证了引文中提到的:

it would not be atypical to see structures padded to align on four- or eight-byte boundaries.(在四字节或八字节边界上对齐的结构并不罕见)

如果一个数据正好存放于这样的一个字节边界上,处理器就能够一次性、高效地读取或写入数据。一旦数据没有对齐,例如对于 32 位的处理器来说,如果跨越两个 4 字节边界存放一个整数(大小 4 字节),那么处理器就需要进行两次内存访问来读取或写入这个整数,导致性能的下降。

这时候可能有朋友会有这样的疑问:

对于一个四字节的变量,我在地址 0、1、2、3 存放处理器能够一次读取出来,那我放到地址 1、2、3、4 不是依然只占用了 4 个字节的空间吗,处理器只需要将读取的偏移地址修改为 1 ,不是照样能一次性读取出来吗?

这个理论看似很合理,确实,仅以我们人类的思维来说是没有任何问题的。但机器不一样。

实际上大部分处理器由于其电路复杂度与成本性价比等原因,在设计之初就决定了只能从与其总线宽度对齐的地址取数据,一旦一个数据跨边界存储,则处理器需要执行两次内存访问操作才能够操作完整的数据。就如上文存放在 1、2、3、4 地址的四字节变量,处理器需要先读取 0-3 区域的 1、 2、3,再读取 4-7 区域的 4 ,最后将其拼接,才能得到 1、2、3、4 这个完整的数据。

并且,有部分处理器完全不支持非对齐的内存访问,一旦代码中访问了非对齐的内存,就会导致硬件异常或者崩溃,无法恢复!

由此可见,内存对齐对于系统的稳定、高效运行是非常关键的,尤其是在一些工业设备上,如果由于非对齐的内存访问并且造成了系统崩溃,其后果是无法估量的!


Henryko 发表于 2024-2-29 22:57 | 显示全部楼层
就是说不对齐运行速度会变慢
小灵通2018 发表于 2024-2-29 23:03 | 显示全部楼层
对齐后可以方便结构体操作吧。
小灵通2018 发表于 2024-2-29 23:03 | 显示全部楼层
一般联合体需要考虑对齐操作。
捉虫天师 发表于 2024-2-29 23:07 | 显示全部楼层
内存对齐对于系统的稳定、高效运行是非常关键的
捉虫天师 发表于 2024-2-29 23:07 | 显示全部楼层
一旦代码中访问了非对齐的内存,就会导致硬件异常或者崩溃
稳稳の幸福 发表于 2024-2-29 23:08 | 显示全部楼层
看应用了,不是所有的应用需要这个。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

262

主题

2024

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部