没有打开用于严格对齐检查的硬件位(在x86上,没有通用的OS实际上要做),AArch64确实允许使用常规的非正常(非设备)内存的未对齐数据访问加载/存储说明。
但是,编译器仍然希望维护对齐数据有几个原因:
- 读写的原子性:自然对齐的加载和存储保证是原子的,即如果一个线程与另一个写入相同位置的线程同时读取对齐的内存位置,则read将只返回旧值或者新的价值。如果位置未与访问大小对齐,则该保证不适用 - 在这种情况下,读取可能返回两个值的未知混合。如果该语言具有依赖于未发生的并发模型,则可能不会允许未对齐的数据。
- 原子读取 - 修改 - 写入操作:如果语言具有并发模型,其中某些或所有数据类型可以原子地更新(不仅仅是读取或写入),那么对于那些操作代码生成将涉及使用load-exclusive / store-exclusive指令来构建原子读 - 修改 - 写序列,而不是普通的加载/存储。如果地址未与访问大小对齐,则独占指令将始终出错。
- 效率:在大多数核心上,最好的未对齐访问至少比正确对齐的访问时间长至少1个周期。在最坏的情况下,单个未对齐访问可以跨越高速缓存行边界(其本身具有额外的开销),并且生成两个高速缓存未命中或甚至两个连续页面错误。除非您处于令人难以置信的内存限制环境中,或者无法控制数据布局(例如,将数据包从网络接收缓冲区中拉出),否则最好避免使用未对齐的数据。
- 必要性:如果语言具有合适的数据模型,即没有指针,并且来自外部源的任何数据已经编组到较低级别的适当数据类型中,那么无论如何都不需要未对齐的访问,并且它使得编译器的生活更容易完全忽略这个想法。
我不知道OCaml特别关注什么,但如果它是“以上所有”,我当然不会感到惊讶。