引言

在处理器架构领域,RISC-V 作为开源指令集架构(ISA)的新星,正在从嵌入式系统向高性能计算、服务器和 AI 芯片领域快速渗透。与 x86 和 ARM 不同,RISC-V 采用了弱内存模型(Weak Memory Model)设计——也就是 RISC-V Weak Memory Order(RVWMO)。这一设计赋予了硬件实现更大的自由度,但也给系统软件开发者带来了全新的挑战。

本文将深入剖析 RISC-V 弱内存模型的核心原理,探讨其与 ARM 弱内存模型的异同,并通过实际代码示例展示如何在 RISC-V 平台上编写正确的并发代码。

一、为什么需要弱内存模型?

在现代乱序执行(Out-of-Order)处理器中,内存访问的实际执行顺序与程序指定的顺序可能不同。这种重排(reordering)是性能优化的重要手段: Store Buffer、Load Buffer、缓存一致性协议等硬件优化都可能引入内存顺序的放松。

强内存模型(如 x86-TSO)要求几乎所有内存操作按序执行,限制了硬件优化空间。弱内存模型则允许更多重排,只要求程序员通过 Fence 指令显式指定需要保序的访问对。

四种基本重排

在弱内存模型中,需要关注以下四种可能的重排情况:

重排类型原始顺序可能被重排为缩写
Load-LoadL1 → L2L2 → L1LL
Load-StoreL → SS → LLS
Store-LoadS → LL → SSL
Store-StoreS1 → S2S2 → S1SS

ARMv7/v8 允许全部四种重排;RISC-V RVWMO 同样允许全部四种重排,但通过 fence 指令提供精细控制。

二、RISC-V RVWMO 核心规则

RVWMO(RISC-V Weak Memory Ordering)的核心原则可以用以下规则概括:

2.1 程序顺序(Program Order)与全局内存顺序

程序顺序(po)指单个 hart(硬件线程)中指令在 ISA 层面的顺序。全局内存顺序(gmo)指所有内存操作在所有 hart 上达成的全局可见顺序。RVWMO 要求:同一 hart 内的 store 操作按程序顺序对其他 hart 全局可见——但这不意味着 load 也会按此顺序观察到。

2.2 保序关系(Preserved Program Order, PPO)

并非所有程序顺序都会被保留。RVWMO 定义了哪些序对是被"保留"的(即不会被重排),主要包括:

  • 地址依赖(Address Dependency): 当后续 load 的地址依赖于前一条 load 的结果时,这两者不会重排
  • 数据依赖(Data Dependency): 后续 store 的数据依赖于前一条 load 的结果时
  • 控制依赖(Control Dependency): 通过分支指令建立的序关系
  • 同一地址的访问: 对同一地址的 load 和 store 按序执行
  • 显式 Fence: fence 指令前后不会被跨越

2.3 FENCE 指令详解

RISC-V 的 fence 指令提供了精细的保序控制:

fence rw, rw   // 全屏障: StoreLoad + Store-Store + Load-Store + Load-Load
fence r, r     // Load-Load 屏障
fence w, w     // Store-Store 屏障
fence r, w     // Load-Store 屏障
fence w, r     // StoreLoad 屏障
fence.tso      // TSO 模式屏障(RISC-V 特有)

三、RISC-V 与 ARM 弱内存模型的对比

特性ARMv8 (ARM)RISC-V RVWMO
基础模型允许全部四种重排允许全部四种重排
屏障指令DMB/DSB/ISBFENCE / FENCE.I / FENCE.TSO
地址依赖保留是是
控制依赖保留有限(仅特定场景)是
Atomic 扩展LSE, LDAPRA 扩展(LR/SC + AMO)
Load-AcquireLDAPR/LDAR带 aq 位的 AMO/LR
Store-ReleaseSTLR/STLRB带 rl 位的 AMO/SC
屏障哲学按领域封装屏障指令按位组合定义细粒度屏障

四、RISC-V 原子操作与 acquire/release 语义

RISC-V A(Atomic)扩展提供两类原子原语:保留加载/条件存储(LR/SC)和原子内存操作(AMO),两者均支持 acquire/release 标记位:

4.1 LR/SC 与 AMO 的 aq/rl 位

// 带 acquire 的加载: 后续内存操作不会被重排到之前
lr.aq t0, (a0)      // Load Reserved with Acquire

// 带 release 的存储: 前面内存操作不会被重排到之后
sc.rl t1, t2, (a0)  // Store Conditional with Release

4.2 C++ Memory Mapping

// C++ memory_order → RISC-V 指令映射
// memory_order_relaxed → 普通 load/store
// memory_order_acquire  → fence r,rw / lr.aq
// memory_order_release  → fence rw,w / sc.rl
// memory_order_acq_rel  → fence rw,rw
// memory_order_seq_cst  → 全屏障 (最强一致性)

五、经典并发模式在 RISC-V 上的实现

5.1 消息传递(Message Passing)

// 线程 A(生产者)
data = 42;
atomic_store(&flag, 1, release);     // store-release

// 线程 B(消费者)
while (atomic_load(&flag, acquire) != 1);  // load-acquire
assert(data == 42);                // 保证看到 data = 42

5.2 Lock-based 互斥锁

// 加锁: amoswap.aq - 原子交换+acquire
lock:
    li   t1, 1
1:  amoswap.aq t0, t1, (a0)
    bnez t0, 1b

// 临界区...

// 解锁: amoswap.rl - 原子交换+release
unlock:
    amoswap.rl x0, x0, (a0)

5.3 Dekker 算法

// Thread 0              | // Thread 1
flag0 = 1;              | flag1 = 1;
fence w, r              | fence w, r    // 关键屏障!
if (flag1 == 0) {       | if (flag0 == 0) {
    // 进入临界区         |     // 进入临界区
}                       | }

六、性能考量与最佳实践

  • 优先使用 acquire/release 语义:比 seq_cst 少一条全屏障指令,性能更好
  • 避免不必要的 StoreLoad 屏障:fence w,r 是开销最大的屏障,仅 Store-Load 跨 hart 依赖时使用
  • 利用地址依赖性:依赖关系天然保序无需额外屏障,如 ptr->data 与 ptr->next
  • 使用 C/C++ 抽象层:C11 <stdatomic.h> 和 C++11 <atomic> 已正确映射到 RISC-V

七、RISC-V 内存模型的发展

  • FENCE.TSO:TSO 屏障,兼容 x86 代码迁移
  • Ztso 扩展:硬件层面 TSO 模式支持
  • Zacas 扩展:提供 CAS 原子操作,增强跨平台兼容性

八、总结

RISC-V RVWMO 的设计哲学是「给硬件最大自由,给程序员细粒度控制」。它不像 ARM 那样封装高层屏障指令,也不是像 x86 那样的模型化 TSO,而是提供一套灵活的组合规则。这种设计让 RISC-V 在嵌入式(简单实现)和高端处理器(激进乱序)之间都能有优秀的实现空间。

理解 RVWMO 对于 RISC-V 系统软件开发至关重要——无论你是编写操作系统内核、驱动程序、运行时还是高性能并发应用,都需要在「性能」与「正确性」之间找到最佳平衡点。

参考资源

  • RISC-V Unprivileged Specification - Section 14 (Memory Model)
  • Waterman, A., & Asanović, K. (2019). The RISC-V Instruction Set Manual, Volume I
  • Maranget, L., Sarkar, S., & Sewell, P. (2012). A Tutorial Introduction to ARM and POWER Relaxed Memory Models
点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
网站二维码

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部