riscv64 原子指令体系调研:Zaamo / Zalrsc / Zacas / Zabha / Zalasr / Ztso
riscv64 原子指令体系调研:Zaamo / Zalrsc / Zacas / Zabha / Zalasr / Ztso
版本:v1.0 · 2026-09-04 读者画像:RISC-V CPU 软件性能优化工程师 调研目的:理解原理为主,建立原子扩展家族的全景地图,识别性能问题域 覆盖范围:六个原子相关扩展的规范语义 · 与 RVWMO 内存模型的关系 · 编译器/内核生态支持度 · 微架构与性能考量
可靠性标注约定
| 标记 | 含义 |
|---|---|
| C | 已核实:本次调研中在线核实(docs.riscv.org 规范 / GitHub / GCC 文档 / LWN) |
| C* | 基础常识:规范级稳定知识,标注了建议核对的章节出处,未逐条在线复核 |
| S | 单一来源:仅搜索摘要或单一来源支持,未交叉验证 |
| ? | 未能核实:留空而非填充估计值 |
1. 总览:为什么"A 扩展"变成了一个原子扩展家族
历史上 RISC-V 的原子能力由单一的 A 扩展承载(LR/SC + AMO)。现行 ISA 把它拆分为多个独立扩展,每个解决一类具体的能力缺口 C:
| 扩展 | 解决的问题 | 规范状态 | 等级 |
|---|---|---|---|
| Zaamo | AMO 指令(原子读-改-写) | Ratified,v1.0 | C |
| Zalrsc | LR/SC(乐观并发原语) | Ratified,v1.0 | C |
| Zacas | 硬件 CAS(amocas.w/d/q) | Ratified,v1.0.0 | C |
| Zabha | 字节/半字 AMO | Ratified,v1.0 | C |
| Zalasr | 显式 load-acquire / store-release | Ratified,v1.0 | C |
| Ztso | TSO 内存模型实现模式 | Ratified,v1.0 | C |
拆分的工程动机(规范 rationale 原文)C:"CAS atomic instructions scale better to highly parallel systems than LR/SC."——即 LR/SC 在高并行度下的可扩展性问题,是 Zacas 出现的根本原因。这句话是理解整个原子扩展家族演进的钥匙。
性能工程师视角:这六个扩展不是并列的功能列表,而是一条"从乐观并发到确定性并发、从粗粒度内存序到细粒度内存序"的演进线。你的优化工作会集中在两条线上:(1) 并发原语的选择与开销;(2) 内存序保证的最小化。
2. 基础层:Zaamo 与 Zalrsc
2.1 Zaamo:AMO 指令族
RV64 下的 AMO 指令(.w = 32 位,.d = 64 位)C*(出处:非特权 ISA Zaamo 章节):
| 指令 | 操作 |
|---|---|
amoswap.w/d | 原子交换 |
amoadd.w/d | 原子加 |
amoxor.w/d | 原子异或 |
amoand.w/d | 原子与 |
amoor.w/d | 原子或 |
amomin.w/d / amomax.w/d | 有符号最小/最大 |
amominu.w/d / amomaxu.w/d | 无符号最小/最大 |
每条 AMO 可附加 .aq / .rl / .aqrl 后缀声明内存序意图(见 §7)。
语义本质 C*:AMO 是单指令完成的原子读-改-写——硬件保证"读取→计算→写回"对同一地址原子发生。典型用途:计数器(amoadd)、自旋锁的 test-and-set(amoswap/amoor)、位掩码操作(amoand/amoor)。
2.2 Zalrsc:LR/SC 与 forward progress 约束
语义 C*:
lr.w/d:加载并建立 reservation(硬件记录"我正在监视这个地址")sc.w/d:仅当 reservation 仍有效时才写入;失败返回非零
constrained LR/SC loop 规则 C*(出处:非特权 ISA Zalrsc 章节,建议核对原文):为保证 forward progress,规范要求约束循环内至多 16 条指令,且不得包含除 SC 之外的内存访问、分支跳转、系统指令等。超出约束的 LR/SC 循环不享有 forward progress 保证——这是写自旋原语时的硬性约束。
ABA 问题 C:规范 rationale 明确指出 CAS 类原子指令的价值之一是"support implementation of algorithms for ABA problem avoidance"。LR/SC 天然免疫 ABA(reservation 监视地址而非值),而朴素 CAS 循环会受 ABA 影响——这是 §3 中 128 位 CAS 用途的背景。
2.3 AMO vs LR/SC:选择依据
| 维度 | AMO(Zaamo) | LR/SC(Zalrsc) |
|---|---|---|
| 表达能力 | 固定操作集(add/and/or/xor/min/max/swap) | 任意读-改-写逻辑(含 CAS、复杂条件更新) |
| 指令数 | 1 条 | ≥2 条 + 循环重试 |
| 高并行度可扩展性 | 好 | 差(规范 rationale 原话)C |
| 重试行为 | 无重试 | 竞争时重试风暴 |
实践判断 C*:能用 AMO 表达的操作优先用 AMO;需要任意逻辑时用 LR/SC 循环——而在有 Zacas 的平台上,CAS 循环应改用 amocas。
3. Zacas:硬件 CAS
3.1 指令与语义 C
amocas.w/d/q,支持.aq/.rl/.aqrlamocas.q(128 位 CAS)使用寄存器对:rd/rd+1 与 rs1/rs1+1(偶数寄存器对齐)- 规范版本 v1.0.0
3.2 为什么需要硬件 CAS
三个层次的理由:
- 可扩展性:LR/SC 的 CAS 循环在高竞争下重试率飙升;单指令 CAS 无重试语义 C(rationale 原话)
- ABA 规避:128 位 CAS 允许"值 + 版本号"打包原子更新——无锁数据结构的经典手法(versioned pointer)C*
- 指令数收缩:CAS 循环 ≥3 条指令 + 分支 + 重试;
amocas.d一条完成。对锁获取路径这种每操作执行频次极高的代码,收缩比例直接反映到吞吐
性能工程师视角:amocas.q的存在让 RISC-V 第一次具备与 x86lock cmpxchg16b、ARM LSECASP对等的 128 位原子 CAS 能力。这是无锁编程范式(seqlock-free、tagged pointer、lock-free queue)在 RISC-V 上完整落地的前提。
4. Zabha:字节/半字原子
4.1 指令 C
为全部 AMO 操作增加 .b(字节)与 .h(半字)变体(如 amoadd.b/h、amoswap.b/h)。
4.2 为什么需要 C
规范 rationale 原文:没有字节级原子时,软件模拟"introduces issues related to scalability and fairness"——即在共享字上用 LR/SC 模拟字节原子操作时,多核争抢同一 cache line 引发可扩展性与公平性问题。
典型需求场景 C*:内核 atomic_t 的字节级操作、锁的字节位标记、引用计数的紧凑布局。
4.3 设计取舍 C
Zabha 刻意不提供字节/半字的 LR/SC——规范认为低实用性。即:字节级原子只能走 AMO 路线,复杂逻辑仍需回退到字级 LR/SC。
5. Zalasr:显式 load-acquire / store-release
5.1 指令表 C
| 类别 | 指令 |
|---|---|
| Load-acquire | lb.aq / lb.aqrl、lh.aq / lh.aqrl、lw.aq / lw.aqrl、ld.aq / ld.aqrl |
| Store-release | sb.rl / sb.aqrl、sh.rl / sh.aqrl、sw.rl / sw.aqrl、sd.rl / sd.aqrl |
5.2 为什么 fence 不够 C
规范表述:Zalasr 提供比 fence 更细粒度的同步——单向 fence 语义。对比:
| 手段 | 语义 | 粒度 |
|---|---|---|
fence rw,rw | 全序屏障,所有方向 | 粗,影响所有内存操作 |
fence r,w | 仅约束"先前 load → 后续 store" | 中 |
lw.aq | 仅这一次 load 具有 acquire 语义 | 细,单操作级 |
fence 的问题 C*:fence 是独立指令,作用于其后所有内存访问序列;acquire/release 是附着在单次访问上的属性。fence 粒度粗导致微架构上需要更保守的处理(排空写缓冲、限制乱序窗口),而单次 acquire load 只需约束该访问的排序关系。
5.3 提案论文的关键结论 C
论文 Adding Explicit Load-Acquire and Store-Release Instructions to the RISC-V ISA(Arden, Susskind, Sweeney,2023-09-02,arXiv 2302.03732):
- 动机:"prevent multiple ABI implementations and ecosystem fragmentation"——各家自行用 fence 模拟 acquire/release 会导致生态碎片化。这是 Zalasr 被标准化的首要原因(生态一致性 > 性能)。
- 反直觉结论:高竞争负载下"更少内存序"的收益是 muted(被掩盖的)——竞争本身的 cache line 乒乓开销主导了性能,内存序指令的差异被淹没。
性能工程师视角:Zalasr 的性能收益预期要分场景设定——低竞争路径(如 RCU 读侧、seqlock 读侧、发布-订阅指针)收益明显;高竞争锁路径收益有限(论文结论 C)。把 Zalasr 当作"fence 的替代品"来做全局优化,收益可能低于预期。
5.4 内核侧进展 C
Linux 内核 Zalasr 支持的 RFC(Xu Lu,2025-08-26,LWN 1035244):目标原语是 smp_load_acquire 与 smp_store_release——即内核的 acquire/release 语义原语将直接映射到 Zalasr 指令,替代当前的 fence 组合。
6. Ztso:TSO 内存模型模式
6.1 语义 C
Ztso v1.0 在 RVWMO 之上施加 TSO(Total Store Ordering)语义:所有 load 隐含 acquire、所有 store 隐含 release。
6.2 对 fence 的影响 C
规范表述:Ztso 下大部分 PPO 规则变得冗余,不带 I/O 位、无 PW/SR 位的 fence 大多成为冗余指令。
6.3 软件含义 C*
- 同一二进制可跨 RVWMO 与 Ztso 平台运行:fence 与
.aq/.rl在 TSO 平台上是冗余但合法的(保守即可正确)。 - 性能含义:Ztso 平台上冗余 fence 是否被微架构零成本处理,是实现相关的问题——不能假设"TSO 平台上 fence 免费",需要实测。
- 判断:Ztso 主要价值是降低移植成本(x86 语义习惯的软件直接跑),而非提供性能优势;真正的性能优化方向仍是 Zalasr 式的细粒度排序。
7. 内存序全景:RVWMO、fence 与 .aq/.rl 的关系
7.1 三层排序机制 C*
| 层次 | 机制 | 说明 |
|---|---|---|
| 全局模型 | RVWMO | 弱内存序,PPO(Preserved Program Order)规则定义保留序 |
| 显式屏障 | fence | fence rd,wr,rr,ww + I/O 位(pi/po/pr/pw)组合 |
| 单操作语义 | .aq / .rl / .aqrl(AMO/LR/SC)与 Zalasr(普通 load/store) | 附着于单次访问 |
7.2 fence.tso C*
fence.tso 是特化 fence(仅保留"先前 load → 后续 store"方向,即 fence r,w 子集),专为 TSO 模式下的最小排序需求设计——在 Ztso 平台上替代 fence rw,rw 的标准手段。
7.3 C11 atomics 的映射 C*
| C11 memory_order | RVWMO 平台典型实现 | Zalasr 平台实现 |
|---|---|---|
| relaxed | 普通 load/store | 同左 |
| acquire | load + fence r,rw | lw.aq / ld.aq |
| release | fence rw,w + store | sw.rl / sd.rl |
| acq_rel | fence 组合或 AMO .aqrl | Zalasr .aqrl 变体或 AMO .aqrl |
| seq_cst | fence rw,rw 组合 | fence 仍需要(Zalasr 不等价 seq_cst) |
性能工程师视角:这张表就是你的优化地图。每一次"load + fence"到"load.aq"的替换,都是删除一条独立屏障指令——在低竞争路径上这是纯收益;在高竞争路径上收益被竞争开销掩盖(§5.3 论文结论)。
8. 生态支持度矩阵
8.1 规范与 Profile
| 项 | 状态 | 等级 |
|---|---|---|
| 六个扩展规范 | 全部 Ratified(v1.0 / v1.0.0) | C |
| RVA23U64 | 强制 Zicclsm、Za64rs;Zabha/Zacas 列为 development options(开发选项,非强制) | C(规范页面,细节建议复核原文) |
| Zalasr/Ztso 在 RVA23 中的位置 | 本次未核实到明确条目 | ? |
8.2 编译器 C(GCC 文档)/ S(LLVM)
| 扩展 | GCC | LLVM |
|---|---|---|
| Zaamo / Zalrsc | 支持(v1.0)C | Assembly Support S |
| Zacas | 支持(v1.0)C | Supported S |
| Zabha | 支持(v1.0)C | Supported S |
| Zalasr | 支持(v1.0)C | Supported S |
| Ztso | 支持(v1.0)C | Supported S |
GCC 文档说明:-march 中显式加入扩展后,依赖扩展会被隐式补齐。C
8.3 Linux 内核
| 项 | 状态 | 等级 |
|---|---|---|
| CONFIG_RISCV_ISA_ZACAS | 存在;启用后内核 atomic cmpxchg 走 amocas;依赖 CONFIG_RISCV_ALTERNATIVE(alternatives 机制做运行时指令替换) | C |
| 主线合并窗口 | riscv-for-linus-6.13 合并标签含 Zacas 相关系列 | S |
| CONFIG_RISCV_ISA_ZABHA | 存在 | C |
| Zalasr 支持 | RFC 阶段(Xu Lu,2025-08-26),目标 smp_load_acquire / smp_store_release | C |
关键机制:内核通过 alternatives(运行时根据 ISA 探测结果替换指令序列)使用新原子扩展——同一内核二进制在有无 Zacas/Zabha 的平台上自动选择最优路径。这与你做用户态优化时的思路一致:运行时探测 + 指令替换。
8.4 其他生态 S
- OpenJDK:JDK-8315856 "RISC-V: Use Zacas extension for cmpxchg"——JIT 层同样走扩展探测路线。
9. 微架构与性能考量(性能工程师核心区)
9.1 LR/SC 重试风暴
reservation 失效的典型原因 C*:其他核写入同一 cache line、cache line 被逐出、中断/异常打断循环、(部分实现)同核其他内存访问。
性能含义:高竞争下 SC 失败率上升 → 循环重试 → 每次重试都是一次完整的 LR→SC 序列 + 可能的 cache line 所有权重新获取。这是规范 rationale 判定"LR/SC 不如 CAS 可扩展"的微架构根源。
优化手段 C*:
- 缩小临界区、降低共享变量争用密度
- 避免在约束循环内做任何多余操作(16 条指令限制同时是性能预算)
- 竞争不可避免时改用 AMO(Zaamo)或
amocas(Zacas)
9.2 AMO 与 cache line 所有权
AMO 的每次执行都要求该 cache line 处于独占状态(需要写权限)C*。多核高频 AMO 同一地址 = cache line 在核间乒乓——这是原子操作高竞争开销的本质,与指令选择无关。论文结论(§5.3)"高竞争下内存序收益被掩盖"正是这个现象的体现。
优化手段 C*:per-CPU/per-thread 计数 + 聚合、cache line 对齐隔离(避免 false sharing)、降低原子操作频率(batch)。
9.3 CAS 循环 vs 硬件 amocas
| LR/SC CAS 循环 | amocas.d | |
|---|---|---|
| 指令数 | ≥3 + 分支 | 1 |
| 竞争行为 | SC 失败重试 | 硬件内部处理,无软件重试 |
| 可扩展性 | 差(rationale 原话)C | 好 |
| 128 位 | 不支持 | amocas.q(寄存器对)C |
9.4 Zalasr vs fence 的收益场景
| 场景 | 预期收益 | 依据 |
|---|---|---|
| 低竞争读侧(RCU、seqlock、指针发布) | 明显——删除独立屏障指令 | 机制分析 C* |
| 高竞争锁路径 | 有限——竞争开销主导 | 论文结论 C |
| TSO 平台上的冗余 fence | 实现相关,需实测 | §6.3 |
9.5 横向对比 C*
| x86-64 | ARMv8.1-A(LSE) | riscv64(全扩展) | |
|---|---|---|---|
| 原子 RMW | lock add 等前缀 | LDADD / SWP 等 | Zaamo amoadd 等 |
| CAS | lock cmpxchg | CAS / CASP | Zacas amocas.w/d/q |
| 128 位 CAS | lock cmpxchg16b | CASP | amocas.q |
| 字节/半字原子 | 天然支持 | LSE 天然支持 | Zabha |
| load-acquire/store-release | (x86 TSO 天然) | LDAPR / STLR | Zalasr |
| 乐观并发原语 | 无对应 | 无对应(LSE 取代) | Zalrsc LR/SC(保留) |
观察:RISC-V 是唯一同时保留乐观并发(LR/SC)与确定性 CAS(Zacas)两条路线的主流 ISA——这是历史包袱也是灵活性。x86/ARM 都走了"确定性原子指令"单路线。
9.6 RVA23 的现实约束 C
Zabha/Zacas 在 RVA23 中仅是 development options——意味着合规 RVA23 平台不保证有硬件 CAS 和字节原子。软件必须保留 LR/SC 回退路径(内核 alternatives 机制正是为此设计 C)。做性能优化时不能假设目标平台必有 Zacas。
10. 学习路径与实验建议
10.1 阅读顺序
- 非特权 ISA 文档:Zaamo → Zalrsc → Zacas → Zabha → Zalasr → Ztso 六章(均已 ratified,v20260120 版)C
- RVWMO 解释材料(PPO 规则逐条读)C
- 规范 rationale 章节(理解设计取舍)C
- arXiv 2302.03732(Zalasr 提案论文)C
10.2 实验建议(按性价比排序)
- CAS 对比实验:同一 cmpxchg 逻辑,LR/SC 循环 vs
amocas.d,扫描竞争核数,画重试率与吞吐曲线。直接验证 rationale 的可扩展性论断。 - fence vs Zalasr 实验:低竞争发布-订阅路径上,"load+fence r,rw" vs "ld.aq",测每操作周期差。验证 §5.3 论文结论在你的微架构上是否成立。
- 128 位 CAS 实验:用
amocas.q实现 versioned pointer 的无锁栈,对比 LR/SC 版本。 - 字节原子实验:共享字上 LR/SC 模拟 vs Zabha
amoadd.b,验证"scalability and fairness"论断。
10.3 模拟器支持 ?
QEMU / Spike / gem5 对 Zacas/Zabha/Zalasr/Ztso 的支持版本本次未在线核实——动手前先确认你的模拟器版本支持目标扩展。
11. 不确定性清单
| 项 | 状态 |
|---|---|
| RVA23 中 Zalasr/Ztso/Zicbom 的确切条目 | 规范页面抓取结果简略,未逐条确认 ? |
| LLVM 各扩展支持的具体版本号 | 文档未列出版本 S |
| Zacas 内核支持的确切主线版本 | 合并标签指向 6.13,kernelconfig 另显示 stable backport 列表,存在口径差异 S |
| 模拟器(QEMU/Spike/gem5)扩展支持矩阵 | 未核实 ? |
| LR/SC constrained loop 的 16 条指令细则 | 基础常识 C*,建议核对非特权 ISA 原文 |
| Ztso 平台上冗余 fence 的微架构成本 | 实现相关,无公开数据 ? |
12. 参考来源
规范(docs.riscv.org,v20260120 版,全部 ratified)
- Zaamo/Zalrsc 规范仓库
- Zacas — Atomic Compare-and-Swap
- Zabha — Byte and Halfword Atomic Memory Operations
- Zalasr — Atomic Load-Acquire and Store-Release
- Ztso — Total Store Ordering
- RVWMO 解释材料
- Historical Rationale for Extensions
- RVA23 Profiles
论文与内核
- Arden, Susskind, Sweeney — Adding Explicit Load-Acquire and Store-Release Instructions to the RISC-V ISA(arXiv 2302.03732,2023-09)
- riscv: Add Zalasr ISA extension support(LWN 1035244,2025-08-26)
- CONFIG_RISCV_ISA_ZACAS · CONFIG_RISCV_ISA_ZABHA
工具链
其他
- JDK-8315856 — RISC-V: Use Zacas extension for cmpxchg
- RISC-V profiles – why is RVA23 significant?(Ubuntu)
附:方法说明
本报告通过 Web 检索 + docs.riscv.org 一手规范交叉验证生成。六个扩展的规范状态、指令表、rationale 引文均为在线核实(C);内存模型基础语义(C*)为规范级稳定知识,标注了核对出处但未逐条在线复核。所有 ? 级条目为真实核查缺口。