ARMv8、AArch64 与 arm64:命名与体系结构要点
ARMv8 指 ARM 架构的一个主版本代际;AArch64 是该代际下的 64 位执行状态与 A64 指令集;arm64 与 aarch64 是操作系统与工具链中对 AArch64 的常用三元组/目录名,二进制约定一致。下文归纳三者关系,并简述与 x86-64 的差异、ARMv9 相对 v8 的扩展方向,以及 AArch64 上常见的编译与优化注意点。
目录
- [ARMv8、AArch64、arm64 的关系](#ARMv8、AArch64、arm64 的关系)
- [ARMv8 架构概要](#ARMv8 架构概要)
- [AArch64 执行状态](#AArch64 执行状态)
- [arm64 / aarch64 在工程中的含义](#arm64 / aarch64 在工程中的含义)
- [AArch64 与 x86-64 的对比](#AArch64 与 x86-64 的对比)
- [ARMv9 相对 ARMv8 的演进方向](#ARMv9 相对 ARMv8 的演进方向)
- [AArch64 开发与优化要点](#AArch64 开发与优化要点)
- 「易混名」与踩坑速查
- 参考链接
ARMv8、AArch64、arm64 的关系
工程侧(64 位用户态)
规范侧
ARMv8 架构代际
(手册里的「架构版本」)
AArch64:64 位执行状态
A64 指令集
AArch32:32 位执行状态
与 ARMv7 同宗语义空间
arm64 / aarch64
arm64-v8a(Android ABI 名)
≠ 新指令集,仅为别名与目录惯例
| 术语 | 性质 | 说明 |
|---|---|---|
| ARMv8 | 架构版本名 | 一代架构规范;同时定义 64 位 AArch64 与 32 位 AArch32 等执行状态 |
| AArch64 | 执行状态 / ISA | ARMv8 中的 64 位模式,使用 A64 指令集 |
| arm64 | 工程别名 | Linux arch/arm64/、Apple 报告架构名等;与 aarch64 在目标三元组、代码生成上等价 |
记忆 :先有规范里的 ARMv8 + AArch64 ,再有 OS/包管理里的 arm64 / aarch64 字符串;二者不是两套 ABI。
ARMv8 架构概要
ARMv8 是 ARM 首次在架构规范层面系统化引入 64 位的代际,主要包括:
- AArch64:64 位执行状态,A64 指令集,通用寄存器宽度 64 位。
- AArch32:32 位执行状态,沿用与 ARMv7 相近的 A32/T32 指令集语义空间,用于兼容既有 32 位软件路径。
具体是否在同一颗核上同时提供 AArch32、EL 层级上如何限制 32 位,由实现与产品配置决定。
AArch64 执行状态
要点如下(细节以 Arm Architecture Reference Manual 为准):
- 通用寄存器 :31 个 64 位(
X0--X30),SP、PC用法与 AArch32 不同。 - 指令编码 :A64 指令定长 32 位。
- 虚拟地址:64 位 VA 空间模型,实际可用宽度受实现与页表配置约束。
- 异常模型 :异常级别 EL0--EL3,与特权级、安全状态、虚拟化等机制配合。
AArch64 是规范中的完整 64 位执行环境,而不是「在 AArch32 上简单扩展出 64 位」的附属模式。
异常级别 EL(示意)
特权与异常路由以 EL0--EL3 分层(与安全世界、虚拟化组合细节见 Arm ARM)。
EL3
Secure Monitor / Firmware
EL2
Hypervisor
EL1
OS 内核
EL0
用户态应用
(上图箭头表示特权级由高到低,不是日常函数调用顺序;实际异常/陷入路径以 ARM ARM 为准。)
| 级别 | 典型用途(概括) |
|---|---|
| EL0 | 应用、绝大多数用户态库 |
| EL1 | 操作系统内核(非虚拟化宿主常见平层) |
| EL2 | Hypervisor(KVM、Type-1/2 虚拟化相关) |
| EL3 | 安全监控、部分固件/安全世界入口 |
arm64 / aarch64 在工程中的含义
arm64 并非 Arm 手册里的架构正式名称,而是社区与厂商惯用叫法,常见出现位置包括:
- Linux 内核 :
CONFIG_ARM64,源码树arch/arm64/。 - GCC / Clang 目标三元组 :如
aarch64-linux-gnu;交叉工具链前缀常见aarch64-*-或发行版打包的arm64-*-。 - Android ABI 目录名 :
arm64-v8a表示基于 ARMv8 AArch64 的用户态 ABI。 - macOS / Apple Silicon :系统与编译器报告
arm64,底层 ISA 仍为 AArch64。
在「同一工具链、同一 ABI、同一调用约定」前提下,arm64 与 aarch64 目标生成的机器码一致;差异主要在命名与打包习惯。
ABI 与运行环境命名速查
| 场景 | 常见标识 | 备注 |
|---|---|---|
Linux uname -m |
aarch64 |
多数发行版 |
| macOS / iOS 报告 | arm64 |
底层仍为 AArch64 |
| Debian 等软件包架构 | arm64 |
与 uname 字符串可能不一致,以发行版文档为准 |
| GCC/Clang 目标三元组 | aarch64-linux-gnu、aarch64-apple-darwin 等 |
交叉前缀常为 aarch64-*- |
| Go | GOARCH=arm64 |
与 Linux/macOS 统一用 arm64 |
| Rust 常见 GNU/Linux 目标 | aarch64-unknown-linux-gnu |
musl 变体见 aarch64-unknown-linux-musl |
| .NET RID | linux-arm64、osx-arm64 |
运行时与原生互操作文档另有说明 |
| Docker / OCI | linux/arm64 |
docker buildx --platform 常用 |
| Android NDK ABI 目录 | arm64-v8a |
表示 ARMv8 AArch64 用户态 ABI,不是「第八版 arm」 |
| Windows on ARM | ARM64(含内核/用户模型分层) |
与 纯 Linux 用户态 ABI 不同,勿混用二进制 |
跨平台流水线建议:以「官方文档里的架构字符串」为准 做映射表,不要手写 if arm64 == aarch64 硬编码散落各处。
AArch64 与 x86-64 的对比
下表为 Instruction Set Architecture 层面的粗粒度对照,微架构实现(解码器、μop、功耗)另当别论。
| 维度 | AArch64(常称 arm64) | x86-64 |
|---|---|---|
| 风格 | Load/Store 型 RISC 取向 | 历史演进而来的 CISC 取向;实现上常译码为微操作 |
| 指令长度 | 定长 32 位 | 变长(常见 1--15 字节) |
| 通用目的寄存器(数量级) | 31 个 64 位(X0--X30) |
16 个 64 位(含扩展约定) |
| 访存 | 算术/逻辑多在寄存器完成;显式 ldr/str 等 |
允许单条指令对内存读改写(如 add [mem], reg) |
| 寻址模式 | 相对规整、种类少于 x86 | 模式丰富(基址+变址+比例因子+位移等) |
| 历史兼容 | AArch64 与 AArch32 为不同执行状态;64 位 ELF 不承载 x86 | 长期兼容 16/32 位 x86 语义子集 |
| ISA 扩展 | 常以功能扩展块形式出现(如 Crypto、SVE/SVE2、BTI、MTE 等) | SSE/AVX 等 SIMD 与各类扩展堆叠 |
| 内存模型(程序员可见层面) | 弱序为主,跨核有序常需原子与屏障配合 | 对程序员常呈现较强顺序(如 TSO 类语义),仍须按语言内存模型使用原子 |
x86-64 实现中常将复杂指令拆成微操作;AArch64 则偏向在 ISA 层保持较规整的编码与译码路径。
弱序与并发(工程心智)
| 要点 | AArch64 侧 |
|---|---|
| 默认假设 | 多核下 Store/Load 重排并不罕见;勿手写「隐形全栅栏」 |
| 正确用法 | 使用语言/标准库原子 API (C11 atomic_*、C++ std::atomic、java.util.concurrent 等) |
| 手写汇编/内联 | dmb/dsb/isb 等与 Shareability 域搭配;无必要时交给编译器 |
| 调试 | 数据竞争在 x86 上「偶发能跑」在 ARM 上更容易暴露,跨架构 CI 很有价值 |
ARMv9 相对 ARMv8 的演进方向
ARMv9-A 在继续以 AArch64 为主执行状态 的前提下做能力扩展,目标是在保持 AArch64 软件兼容的基础上引入安全、向量与系统级特性(具体必选/可选特性因 profile 与实现而异)。
常见公开材料中涉及的方向性变化包括(产品是否实现、固件/内核是否启用需逐平台核对):
- AArch32 :在部分 v9 产品上用户态仍可能保留,内核态 AArch32、新平台上的 32 位支持整体呈收缩趋势。
- SIMD / 向量 :SVE2 等作为 AArch64 上向量能力的重要延伸(向量长度可变实现与固定 128-bit NEON 并存关系依芯片而定)。
- 安全 :如 MTE(内存标签) 、指针认证 PAC 、分支目标识别 BTI 、RME/Realm 机密计算 等扩展,用于降低内存破坏与控制流劫持风险。
- 系统与调试:嵌套虚拟化、Stage-2 MMU 与追踪/分支记录类扩展等,面向服务器与虚拟化场景。
- 事务内存等:部分扩展(如 TME)在生态与实现上需单独查当前内核与芯片支持矩阵。
关于「相对 v8 的 IPC 提升百分比」等表述多来自厂商市场材料,应以同工作负载、同工艺下的实测为准。
ARMv8-A 与 ARMv9-A(方向对照)
| 维度 | ARMv8-A(概括) | ARMv9-A(方向,实现因产品而异) |
|---|---|---|
| 主执行状态 | AArch64 + 可选 AArch32 | 仍以 AArch64 为主;AArch32 支持因产品线收缩 |
| 基线 SIMD | NEON(128-bit)广泛使用 | 常与 SVE/SVE2 能力并陈(硬件是否具备需查 SoC) |
| 安全扩展(示例) | 指针认证 PAC 、BTI 、MTE 等在 v8.x 中分阶段引入 | Realm / RME 等机密计算路线;具体必选集看 Armv9 profile |
| 软件兼容性 | --- | 设计目标为 AArch64 应用级兼容 上连续演进;仍要核对内核/固件最低版本 |
AArch64 开发与优化要点
目标与剖析
微架构(小核/大核、缓存、预取器)差异大;优化前应确定目标 CPU 与系统 ,用 perf 等区分计算 bound 与访存 bound。
编译选项
- 通用优化 :
-O2常用;热点模块可尝试-O3;-Ofast改变浮点语义,科学/金融场景慎用。 - 目标 ISA :例如
-march=armv8-a+crc+crypto等按需要启用扩展;微架构调优可用-mtune=cortex-a78等(名称随工具链与 CPU 更新)。 - SVE/SVE2 :在确认硬件与工具链支持后使用
-march=...+sve等(具体标志以 Clang/GCC 文档为准)。 - LTO :
-flto(配合链接器如 lld)做跨翻译单元优化。 - PGO :
-fprofile-generate采集 →-fprofile-use重编译。
访存与数据布局
- SIMD 与原子场景注意 对齐(如 16 字节、缓存行 64 字节等)。
- 热点路径减少动态分配;字段布局提高空间局部性;批处理提高缓存与预取利用率。
向量(NEON / SVE)
AArch64 上 NEON 广泛使用;可在 C/C++ 中通过 arm_neon.h 等接口或编译器自动向量化。示例(向量加法骨架):
c
#include <arm_neon.h>
void vector_add(const float *a, const float *b, float *c, int n) {
for (int i = 0; i + 4 <= n; i += 4) {
float32x4_t va = vld1q_f32(&a[i]);
float32x4_t vb = vld1q_f32(&b[i]);
vst1q_f32(&c[i], vaddq_f32(va, vb));
}
/* 尾部标量处理略 */
}
支持 SVE/SVE2 时,可在确认 ABI 与运行时检测的前提下编写与向量长度无关的内核(需查阅编译器 intrinsics 与 Arm ACLE)。
控制流与内联
热点小函数 static inline ;__builtin_expect 提示分支概率;复杂分支有时可让编译器生成跳转表(依代码形态而定)。
并发与内存序
弱序模型下,跨线程数据竞争须由语言内存模型 (如 C++ memory_order)或明确的原子/屏障保证;不要依赖「隐式全序」假设。
验证
-S 查看汇编是否出现预期向量指令与循环形态;perf record / perf report 看 IPC 与缓存;微基准注意计时与噪声。
交叉编译与链接(顺带)
| 环节 | 提示 |
|---|---|
| Sysroot | 交叉构建时 --sysroot 与 PKG_CONFIG_PATH 需指向 目标架构 头文件与库 |
qemu-user 测集成 |
功能冒烟可行;性能与 simd/原子行为仍以真机为准 |
-mcpu / -mtune |
Apple Silicon 与服务器 Neoverse 等微架构名不同,勿复制粘贴 x86 习惯 |
「易混名」与踩坑速查
| 现象 | 说明 |
|---|---|
| arm vs arm64 | arm / armv7 多为 32 位 AArch32 ;arm64 为 64 位 AArch64;二者 ELF 与调用约定不同 |
| arm64-v8a | Android ABI 名;v8a 指 ARMv8 AArch64,不是「比 arm64 新一档」的独立 ISA |
| uname 与 deb 架构字符串不一致 | 例如在部分生态中 uname 显示 aarch64 而包架构写 arm64,CI 脚本要查发行版约定 |
| 同 GOOS 不同 libc | aarch64-linux-gnu(glibc)与 *-musl 二进制一般不混用 |
| Windows ARM64 与 Linux arm64 | PE/COFF vs ELF,不能直接互换可执行文件 |
参考链接
- Arm 官方架构与文档入口:Arm Architecture
- Linux 内核 AArch64 文档索引:ARM64 Architecture --- The Linux Kernel documentation
本文用于术语梳理与工程向导读,寄存器、异常、扩展特性等以对应版本的 Arm ARM 与工具链发行说明为准。