AArch64 是不是支持非对齐访问?

Posted

技术标签:

【中文标题】AArch64 是不是支持非对齐访问?【英文标题】:Does AArch64 support unaligned access?AArch64 是否支持非对齐访问? 【发布时间】:2016-11-26 21:44:32 【问题描述】:

AArch64 是否原生支持非对齐访问?我问是因为目前ocamlopt 假设“否”。

【问题讨论】:

“是的,如果没有启用严格的对齐检查,除非在所有没有启用(或启用但您不想要副作用)的情况下”可能是总结。是否支持您正在尝试做的事情取决于那是什么,并且由于我对 OCaml、它的 ABI、数据类型以及它用于什么的机器指令了解为零,即使有细节我也怀疑最终答案将来自我:/ 从内存中加载 16、32 和 64 位值。没有 SIMD 等。 对于堆栈 SP 访问的特定情况,它似乎可以使用 SCTLR_ELx.SASCTLR_EL1.SA0 进行配置,如在 ***.com/questions/212466/what-is-a-bus-error/… 中简要提及的那样: 【参考方案1】:

为严格对齐检查提供硬件位未打开(这与 x86 上一样,实际上没有通用操作系统会这样做),AArch64 确实允许使用常规方法对普通(非设备)内存进行未对齐的数据访问加载/存储指令。

但是,编译器仍希望保持对齐数据的原因有几个:

读取和写入的原子性:自然对齐的加载和存储保证是原子的,即如果一个线程同时读取对齐的内存位置,而另一个线程写入相同的位置,则读取只会返回旧值或新的价值。如果位置未与访问大小对齐,则该保证不适用——在这种情况下,读取可能会返回两个值的未知混合。如果该语言有一个依赖于不发生这种情况的并发模型,它可能不会允许未对齐的数据。 原子读-修改-写操作:如果语言有一个并发模型,其中部分或所有数据类型可以以原子方式更新(不仅仅是读或写),那么对于这些​​操作,代码生成将涉及使用 load-exclusive/store-exclusive 指令来构建原子读取-修改-写入序列,而不是普通的加载/存储。如果地址未与访问大小对齐,则独占指令将始终出错。 效率:在大多数内核上,未对齐的访问充其量仍比正确对齐的访问长至少 1 个周期。在最坏的情况下,单个未对齐的访问可以跨越缓存线边界(这本身就有额外的开销),并产生 两次 缓存未命中甚至两个连续的页面错误。除非您处于非常受内存限制的环境中,或者无法控制数据布局(例如从网络接收缓冲区中提取数据包),否则最好避免未对齐的数据。 必要性:如果该语言有一个合适的数据模型,即没有指针,并且任何来自外部源的数据已经在较低级别编组为适当的数据类型,那么无论如何都不需要非对齐访问,它使编译器的完全忽略这个想法会容易得多。

我不知道 OCaml 特别关注什么,但如果它是“以上所有”,我当然不会感到惊讶。

【讨论】:

其实答案是“以上都不是”:我正在为 OCaml 编写一个原始指针模块。 从对 Godbolt 的快速测试看来,gcc 认为 aarch64 上的非对齐访问是可以的。 @Notlikethat,MMU 在这里会有所帮助吗,假设在 MMU 较少的操作系统上工作会触发更多的未对齐访问?

以上是关于AArch64 是不是支持非对齐访问?的主要内容,如果未能解决你的问题,请参考以下文章

centos aarch64(arm64) iso 下载地址

aarch64 上未对齐 SIMD 加载/存储的性能

卤化物是不是支持带有霓虹灯的 ARMv8(aarch64)?

arm64(aarch64)下使用mysql

华为发布AArch64/Arm64 硬件的 Linux 镜像内存支持

华为发布AArch64/Arm64 硬件的 Linux 镜像内存支持