RISC-V 的原子扩展如何让你具有了出色的位操作能力

2022年04月14日 10:52    发布者:eechina
来源:Digi-Key
作者:Bill Giovino

RISC-V 架构的使用量正滚雪球般地迅速增长,而且有充分的理由相信,这种架构在业内的影响力在逐步扩大。

除了内核架构及其真正的精简指令集架构 (ISA) 外,该架构还通过一系列标准化扩展得到了增强 (图 1) 。例如,按照所示扩展列表,将支持单精度浮点和压缩指令的 32 位 RISC-V 内核 (RV32) 命名为 RV32FC。


图 1:RISC-V ISA 通过一系列标准化指令扩展得到了增强,用内核名称后的一个字母后缀表示。(图片来源:RISC-V.org)

对于许多人工智能 (AI)、机器学习 (ML) 应用以及先进的嵌入式系统,四个最必要的扩展是整数乘除 (M) 、原子指令 (A) 、单精度浮点 (F) 和双精度浮点 (D) 。然而,不是把内核指定为 RV32MAFD,而是把这些都归入 G 后缀,如 RV32G。

关于各种扩展和 RISC-V 的更多信息,参见 Digi-Key 在EDU 网站上发布的 RISC-V 电子书。

就我个人而言,由于我对处理器的最初经验是在深度嵌入式系统方面,我更倾向于密切关注架构对数据存储器的“读改写位操作”的支持。对于这些应用,设置和清除外设寄存器和信号系统的位是很常见的事情。如果没有原生位操作指令,内核需要把数据存储器位置的内容复制到一个内核寄存器,分别使用 OR、AND 或 XOR 指令来设置、清除或切换位,然后把结果仍存储在数据存储器位置。这不仅需要额外的时间,而且在某些情况下,我看到有些嵌入式控制应用的代码膨胀高达 20%。

对于有些应用来说,代码膨胀和性能下降是可以接受的。然而在执行这三条指令时,一个中断就能粗暴地将程序控制权从操作中移除,甚至更糟的是,多处理器系统中的另一个内核可能会从同一内存位置读取数据。禁用中断或锁定存储器以确保这些事件不会破坏数据存储器,这要求另外的指令和可能会造成性能问题的复杂情况。

Arm 试图通过实施“位绑定”来解决这些问题,这种方法对简单的位操作有效。然而在我看来,RISC-V 已经实施了一种更巧妙、更灵活的解决方案。

为什么 Atomic 扩展如此巧妙

RISC-V A(原子)扩展支持两种操作,一种是 Load-Reserved/Store-Conditional 指令(本文将不予讨论);另一种是二进制/位操作指令,可实现对数据存储器的简单位操作。虽然 RISC-V B 位操作扩展支持一系列复杂的位控制指令,但 Atomic 扩展并不只是针对多处理器系统。它也有助于那些必要的位操作需求比较简单的较小嵌入式系统。例如,Seeed Technology 的 114991684 双核 64 位 RISC-V 模块就属于这种系统。该系统包含两个 RV64GC 内核。这两个内核需要很好地协调工作并共享数据 SRAM。

RISC-V A 扩展原子存储器操作 (AMO) 的格式见图 2。


图 2:RISC-V 的 AMO 指令格式仅需一条指令即可支持对数据存储器进行原子二进制操作。(图片来源:RISC-V.org(通过 Bill Giovino 增强))

AMO 是一条强大的“读改写”指令,只需一条指令即可支持直接在 rs1 中指向的数据存储器上进行各种不同的二进制操作。参照图 2,该操作加载 rs1 中数据存储器地址位置的内容,并将该值存储在寄存器 rd 中。然后用 rs2 中的值对 rd 值进行二进制运算,并将结果保存回 rd 中,保存回在 rs1 的数据存储器地址位置。

所支持的二进制操作有 OR(位设置) 、AND(位清除) 和 XOR(位切换) 。这允许直接在数据存储器上对一个或多个位进行原子位操作。这也防止了两个 RV64GC 内核同时使用同一个存储器地址时出现存储器冲突的问题。在配置存储器中的外设寄存器时,这对小型嵌入式应用极为有用,并能简化旗语标操作。

RISC-V AMO 还支持整数最大值、整数最小值和交换。此外,还支持允许直接进行二进制加法的二进制 ADD,包括直接增加数据存储器中的计数器值。

RV64 内核同时支持 32 位和 64 位操作。对于 RV64 的位操作,重要的是它只对 64 位数据进行操作,因为该操作将对放置在 rd 中的 32 位数据进行符号扩展。

总结

RISC-V ISA 是第一个敢于挑战 Arm ISA 的严肃竞争者。它的 ISA 扩展提供了一种标准化方法,通过能够以经济实惠的方式提升应用性能的指令来增强内核。我尤其对可选的 Atomic 扩展感兴奋。

虽然对于多处理器系统来说很有用,而且几乎是必须的,但原子扩展也是一种直接在数据存储器上进行位操作控制的有效方法。与许多现有的架构相比,这种架构优势显著——减少代码长度,提高性能。