【问题标题】:Why accessing non naturally aligned memory is not efficient?为什么访问非自然对齐的内存效率不高?
【发布时间】:2021-12-17 15:23:03
【问题描述】:

假设我们有一个 64 位 cpu,它总是一次读取 8 个字节的内存,我想存储一个 4 个字节的 int。根据自然对齐的定义,一个 4 字节的对象与一个 4 的倍数的地址对齐(例如 0x0000、0x0004)。但是问题来了,为什么我不能将它存储在地址 0x0001 中?据我了解,由于 CPU 总是会读取 8 个字节的数据,因此从地址 0x0000 读取仍然可以一次性获得存储在 0x0001 的 int。那么,为什么在这种情况下需要自然对齐呢?

【问题讨论】:

    标签: memory memory-alignment


    【解决方案1】:

    现代 CPU(Intel、Arm)很乐意从未对齐的地址中读取数据。 CPU 的架构通常每个周期读取超过 8 个字节:可能是 16 个字节或 32 个字节,并且 CPU 的深层管道可以很好地管理从任意地址提取所需的 8 个字节而没有任何明显的损失。

    通常,但并非总是如此,可以编写算法而不用过多关注数组的对齐方式(或二维数组的每一行的开头)。

    流水线架构可能一次读取对齐的 16 字节块,这意味着当从地址 0x0009 读取 8 个字节时,CPU 实际上需要读取 2 个 16 字节块,将它们组合并提取中间的 8 个字节。事情变得更加复杂,当内存在一级缓存中不可用时,需要从下一级缓存或主内存中获取 64 字节的完整缓存行。

    根据我的经验(为 SIMD 编写和优化图像处理算法),对于具有简单和线性内存访问的算法,许多 Arm64 实现几乎完美地隐藏了从未对齐地址加载的成本。情况变得更糟,如果算法需要从许多未对齐的地址中大量读取,例如在使用 3x3 或更大的内核进行过滤时,或者在计算高基 FFT 时,这表明 CPU 传输内存和组合的能力很快就会耗尽。

    【讨论】:

    • 感谢您的回答,您是否建议现代 CPU 可以有效地处理非自然对齐的内存地址?顺便说一句,在上述情况下,某些非“现代”64 位 CPU 无法处理非对齐内存的原因是什么?
    • 设计和实施需要成本。 AFAIK 大部分低成本/低功耗嵌入式 CPU(例如 armv6)都省略了此功能。
    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 2013-03-08
    • 2010-11-07
    • 1970-01-01
    相关资源
    最近更新 更多