打印
[应用相关]

为什么要内存对齐 ?

[复制链接]
578|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 | 只看该作者
一般联合体需要考虑对齐操作。

使用特权

评论回复
5
捉虫天师| | 2024-2-29 23:07 | 只看该作者
内存对齐对于系统的稳定、高效运行是非常关键的

使用特权

评论回复
6
捉虫天师| | 2024-2-29 23:07 | 只看该作者
一旦代码中访问了非对齐的内存,就会导致硬件异常或者崩溃

使用特权

评论回复
7
稳稳の幸福| | 2024-2-29 23:08 | 只看该作者
看应用了,不是所有的应用需要这个。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

231

主题

1538

帖子

2

粉丝