天天看点

RISC-V原子指令LR/SC

LR/SC 指令

LR 指令是 Load Reserved 的缩写,读取保留;SC 指令是 Store Conditional 的缩写,条件存储。

LR 指令格式及其变种如下:

lr.{w/d}.{aqrl} rd, (rs1)

lr 指令是从内存地址 rs1 中加载内容到 rd 寄存器。然后在 rs1 对应地址上设置保留标记(reservation set)。其中 w/d 分别对应 32 位/64 位版本。

SC 指令格式及其变种如下:

sc.{w/d}.{aqrl} rd, rs2, (rs1)

sc 指令在把 rs2 值写到 rs1 地址之前,会先判断 rs1 内存地址是否有设置保留标记,如果设置了,则把 rs2 值正常写入到 rs1 内存地址里,并把 rd 寄存器设置成 0,表示保存成功。如果 rs1 内存地址没有设置保留标记,则不保存,并把 rd 寄存器设置成 1 表示保存失败。不管成功还是失败,sc 指令都会把当前 hart 保留的所有保留标记全部清除。其中 w/d 分别对应 32 位/64 位版本。

内存访问顺序(Memory Order)

RISC-V 和 ARM 类似,内存模型都是弱内存模型(relax memory model),这意味着,在不加额外限制的情况下,内存访问指令并不会完全按照指令顺序执行。RISC-V 有一个 FENCE 指令,可以用来显式添加内存顺序限制。为了提高效率,RISC-V 为每个原子指令都预留 aq/rl 两个比特位,从而可以很方便在原子指令上施加额外的内存顺序限制。原子指令是用来在不同 hart 之间做同步用的,而内存访问顺序强调的是同一个 hart 内的执行顺序。

在上面介绍 LR/SC 和 AMO 指令时,每个指令后面都带有一个 "aqrl" 的可选后缀。aq 是 acquire 的缩写,rl 是 release 的缩写。LR/SC 和 AMO 指令就是通过这两个后缀来添加额外的内存顺序限制。具体定义如下:

虽然 RISC-V 为每个原子指令都预留了 aq/rl 比特位,但对于一些特定指令,aq/rl 不能随便设置。比如 lr.d.rl 和 sc.d.aq 指令是没有实际意义的,RISC-V 并没有直接禁止这种用法,但这种指令没有预期的原子访问效果。

RISC-V原子指令LR/SC

继续阅读