资讯动态

IPADS主导RISC-V指令集扩展写入国际标准:系统软件视角的里程碑

发布时间:2026/9/7 8:28:01 来源:尧图企业网站定制
RISC-V 这几年在国内的热度大家有目共睹芯片公司扎堆做核开源社区拼性能投资人也愿意为自主可控的故事买单。但我一直觉得真正决定 RISC-V 能走多远的不是多核频率多高、IPC 多强而是指令集扩展这件事到底有没有被认真对待。最近看到上海交大 IPADS 团队主导的指令集扩展方案被正式写入 RISC-V 国际标准我第一反应是这事儿终于有标志性进展了。这个事件不是简单的论文落地也不是某家公司的商业产品适配而是一个来自高校系统软件团队的方案被国际标准化组织接纳。对做 RISC-V CPU 设计的人、写 Linux 内核/裸机驱动的人、搞工具链的人甚至准备入行的学生来说都有必要停下来把这件事拆开看一看。我不打算复述新闻通稿而是想从工程师的角度聊聊一次 RISC-V 指令集扩展从提案到进入标准背后要经历什么IPADS 这类以操作系统和体系结构协同设计见长的团队为什么能主导这种工作以及我们这些做软件或者做验证的人应该怎么提前从标准变化里找到自己的切入点。这篇东西你可以当成行业观察也可以当成技术复盘来读我会尽量把原理讲透把流程讲细把我在实际跟踪这类扩展时踩过的坑也一并写出来。1. 为什么基础指令集已经很完备大家还在拼命加扩展1.1 基础指令集只是地基扩展才是真正的生态拼图RISC-V 的核心里面RV32I/RV64I 加上 M、A、F、D、C 这几个基础扩展实际上已经能覆盖不少场景嵌入式控制、浮点运算、原子操作、压缩指令样样都有。但现实需求远比这些组合复杂。你得想想一颗应用处理器的 SoC 要跑 Linux要跑虚拟化要做安全隔离要跑 AI 推理还要做向量计算这些能力不可能全部塞进一块恒定的基础 ISA 里。如果把什么都定义为必须实现那这个架构就会变成第二个 ARM失去轻量和精简的优势。所以 RISC-V 从一开始就选择了另一条路把最小可用指令集和按需扩展的指令集分开。基础 ISA 负责稳定扩展则像乐高积木一样允许厂商按需拼接。这个思路带来的好处是低端 MCU 可以只实现 RV32I 得几十平方毫米的小核高端服务器核可以堆出带向量、虚拟化、IOMMU 的完整能力彼此之间还能保持软件兼容。坏处也很明显——扩展一旦多了标准怎么对齐、软件栈怎么适配、各种组合怎么验证就成了巨大的工程问题。我们平时聊 RISC-V 的时候提到扩展往往停留在指令助记符的层面比如看到V就知道向量扩展看到H就知道 hypervisor 扩展。但真正到了系统层面指令只是最表面的一层。围绕每条指令还要有配套的 CSR、异常行为定义、ABI 约定、调试支持、工具链和模拟器支持。这整套东西才算一个完整的扩展生态拼图。IPADS 这次主导写入国际标准的方案给行业带来的真正价值不单是几个新指令而是把从前各做各的、没法互通的碎片化方案整合成了可以在全世界范围统一实现的规范。1.2 指令集扩展的标准化难的不是硬件设计而是多方共识可能有人会问我的芯片自己做了一组自定义指令用得好好的性能也上去了为什么要去走标准流程有这种想法很正常尤其是做 AI 加速或者做 DSP 场景的团队自定义指令带来的每瓦性能提升非常可观而且可以保护自己的商业壁垒。但问题在于自定义指令出了你这颗芯片就没有生态GCC 和 LLVM 不会专门给你做编译器后端Linux 内核不会贸然用你的指令调试器的支持更是遥遥无期。想让它发挥威力你必须说服更多人一起用这就必须走 RISC-V 国际基金会的 Task Group任务组流程。指令集扩展的标准化过程通常要经历好几个阶段先有 TG 立项然后出提案文档定义指令编码、语义、CSR接着做工具链和模拟器参考实现再搞硬件实现和软件验证最后经过内部评审、公审批次才能正式纳入标准。整个过程短则一年长则三四年。除了技术问题更大的是利益平衡问题。举个很直观的例子半导体公司 A 想推一个安全扩展半导体公司 B 可能已经在内部搞了一套私有方案如果标准采纳了 A 的提案B 就得放弃自己的东西迁移到新标准。这中间的博弈非常现实。所以一个扩展方案能够从邮件列表里的讨论稿一路走到被官方写入标准说明它在通用性、可扩展性、产业价值上说服了足够多的人这个含金量比单纯发表一篇论文高得多。IPADS 团队能走到这一步一个很重要的原因在于他们不是从一个狭窄的商业产品视角出发去设计扩展而是站在系统软件——尤其是操作系统内核——的角度来反推硬件需要提供什么原语。这种OS 与 ISA 协同设计的思路恰好是当前 RISC-V 生态里最稀缺的。2. IPADS 团队主导的这次扩展技术价值究竟体现在哪里2.1 从系统软件视角反推指令集需求是 IPADS 的独门路径上海交大 IPADS 实验室全称是并行与分布式系统实验室在国内操作系统方向算是标杆之一做过很多内核、虚拟化、安全方面的系统性工作。以前大家更多关注他们做的软件系统比如文件系统、内存管理、虚拟化组件但这次的事情很不一样他们把目光投向了指令集本身。传统芯片公司设计指令集更多考虑的是硬件管线怎么实现、面积和时序怎么平衡、benchmark 能跑多高软件团队设计指令集则更多会问Linux 内核在关键路径上需要什么虚拟机切换时哪些开销可以省内存安全标签怎么打才能兼容现有 ABI。IPADS 的优势就在这里他们有充足的内核开发经验知道异常处理路径、TLB 刷新、地址空间切换这些真正降系统性能的痛点在哪里也知道指令集扩展如果设计得跟操作系统对不上软件落地的阻力会有多大。这次写入国际标准的方案具体编码和细节推荐大家直接去看 RISC-V 国际基金会发布的规范原文我这里不替它做过度声称。但按照公开的方向来看它很典型地体现了 IPADS 一贯的研究路线针对系统软件运行时的高频耗损点设计一组轻量但通用的指令级原语让内核在改动尽可能小的情况下就能用上硬件加速能力。这类扩展往往不是在拍脑袋加指令而是先在真实的内核代码里做性能剖析找到热点再设计硬件接口。这种做法的直接产物是新扩展从一开始就有软件需求说明书而不是我们芯片能做所以加一条指令。对生态而言这一点至关重要。因为真正阻碍 RISC-V 进入服务器和桌面市场的从来不是 CPU 算力不够而是软件栈在关键路径上的开销没办法像 x86/ARM 那样成熟。OS 协同设计的扩展恰恰是填这个坑的。2.2 典型痛点地址转换、安全隔离与虚拟化切换ISA 扩展如果面向系统软件通常绕不开这几类经典痛点。第一类是地址转换开销。Linux 用 4 级页表也好5 级页表也好每次 TLB miss 都要走硬件页表遍历碰上进程切换还得面对 TLB 失效的问题这在虚拟化场景下尤其痛苦。第二类是安全隔离。传统的内存安全方案靠 MPU、PMB 或者 MMU 的分页权限位粒度要么太粗要么性能损耗太大业界一直在探索 tag-based 或 capability-based 的硬件辅助方案。第三类是虚拟化切换。在虚拟化场景里guest 和 host 之间的世界切换开销会影响 I/O 虚拟化和中断虚拟化的性能。针对这些点RISC-V 社区其实已经有一些零散的尝试比如用于内存保护的 高位 tagged memory以及用于加速地址空间切换的轻量指令。但问题在于过去这些尝试往往分散在不同厂商或高校的私有实现里面没有统一进标准软件想用都找不到稳定的硬件依据。IPADS 这类团队把方案推到国际标准里等于给大家划出了一个官方铺好的路编译器、内核、虚拟化软件都可以围绕这套正式扩展来迭代而不用伺候一堆互相不兼容的私有分支。标准化带来的迁移成本也很值得多说一句。在扩展还是提案时厂商可以在私有 CPU 上先做验证但一旦国际标准冻结后续所有满足该扩展的处理器都必须行为一致。对于做软件的人这意味着可以放心地在代码里使用这些扩展指令并假设二进制文件可以在不同厂商的芯片上跑出相同结果——这就是生态繁荣的基础也是这次写入标准对整个行业最实质的推动。2.3 一个扩展方案要成为国际标准需要交付哪些东西可能很多读者没接触过 RISC-V 标准化流程我帮大家拆一下一个扩展要拿到转正资格不是写一份 markdown 文档丢到 GitHub 上就完事。第一要有完整指令定义。包括每条指令的编码位域分配、合法/非法组合、CSR 的读写在各种特权级下的行为。第二要有参考实现。通常是一个 QEMU 或者 Spike 上的软件模拟用来让编译器和内核开发者先跑起来。第三要有测试向量。RISC-V 基金会要求扩展必须有 riscv-arch-test 用例别的厂商拿到 spec 后能不能快速验证自己的 IP 是否正确实现全靠这些测试。第四要处理与其他扩展的交互。比如这个新扩展将来跟 H 扩展虚拟化和 V 扩展向量混用时CSR 怎么协同、中断怎么嵌套规则都得预先定义好。IPADS 这次能推动方案走到标准层面起码说明他们在上述环节上都下了不小的功夫。我以前参与过一个小的私有扩展开发光是给 QEMU 配一套带 CSR 的模拟环境就花了两周更不用说写 arch-test。而高校团队在没有大规模硬件验证的条件下能完成这些交付物并让国际社区认可背后是相当大的工程投入。这一点值得所有宣称我们做系统软件很牛的团队对照学习。3. 一个指令集扩展从定义到跑通核心环节怎么拆解3.1 定义指令语义加几条指令牵连的是整条异常与状态路径指令集设计看起来是加几条带助记符的二进制编码但真正做起来会发现你定义一个FENCE变体或者CSR读写行为实际上是在定义整个处理器的状态机边界。最容易被忽略的是异常语义。比如一条新指令在地址无效时应该触发哪种异常异常处理返回后指令是重新执行还是被标记为已完成这条指令如果出现在 32 位和 64 位模式下表现是否一致又比如这条指令和 page fault 并发时CSR 应该保持什么值这些都是要靠规范写清楚、靠硬件与软件共同遵守的契约。我自己的经验是在给一个小众扩展做验证时发现规范里没有明确写未实现该指令时执行非法指令异常是否会被当作指令页错误优先处理。就这么一个看似细枝末节的语义不同模拟器给出了不同行为最后软件启动时莫名挂掉。标准文档里那些必须SHALL应该SHOULD的措辞读者往往觉得枯燥但它们才是基于这套 ISA 构建操作系统的安全网。IPADS 这种团队在设计扩展时一定对异常路径和指令边界做了细致推演才不至于让内核在特定边界条件下触发未定义行为。3.2 软件协同验证QEMU、工具链与内核三件套怎么配合指令集扩展不能只在纸上成立必须有配套的软件实现。最典型的路线是先在 QEMU 的 linux-user 和 system 模式下加入指令翻译逻辑让新的指令在模拟器里可执行接着在工具链GCC/LLVM里加上指令的汇编语法和编译内建函数这样开发者才能写出用这段扩展的 C 语言代码而不是天天手写汇编最后在 Linux 内核里加一个支持该扩展的特性开关让内核启动时检测 CPU 有没有这个能力并在对应的代码路径里启用新指令加速。这三步的顺序很重要。先做模拟器是因为模拟器调试成本低指令行为不对可以随时改工具链上网和汇编支持其实是给上层程序员用的不能太早绑定否则 ABI 一旦调整代码全废内核支持往往要等规范和工具链稳定后才跟进。在实际操作中我发现很多人习惯先把编译器后端写好想快速看生成汇编的效率但稍不注意就陷入编译器生成的指令序列不合法或者寄存器约束和 ABI 冲突这类泥潭里。合理做法是先写一个小型汇编测试集在没有编译器介入的情况下用.insn伪指令直接定义二进制编码验证 QEMU、验证 Spike再回过来写编译器后端。把这一套流程跑通才算是给新指令集扩展打好了软件地基。IPADS 这样的团队之所以能让国际社区认可他们的扩展大概率也是因为他们的方案始终有一整套可运行的参考软件栈——这比单独提交一份规范文档有说服力得多。3.3 性能收益与硬件成本到底怎么平衡任何 ISA 扩展都会问一个问题多了这几条指令换来多少真金白银的性能提升这个提升不仅是跑 benchmark 里的 IPC 或者指令数下降更要看综合时序、流水线复杂度、面积和功耗成本。拿一个用于快速地址空间切换的扩展来说软件上省掉了几十次 CSR 读写和 TLB 刷新的循环但如果硬件要在重命名CSR 上大动干戈关键路径直接被拉长那就得不偿失。所以设计指令集扩展时通用的方法是先建立工作量模型。比如一条SFENCE.VMA被优化成SFENCE.VMA 某种批量失效你可以先统计典型负载下 TLB 刷新的调用频率和失效页数目建模出总耗时再对比新增指令可能带来的流水线停顿之后还要用周期精确模拟器或者 FPGA 原型验证看看真实场景里 IPC 有没有提高。RISC-V 社区常见做法是拿 QEMU 跑整机 Linux benchmark虽然 QEMU 不是周期级模拟但能反映出指令序列长度和基本块热度的变化对早期评估已经很有参考价值。上面的评估过程看起来是硬件团队的事但系统软件团队同样要参与。因为如果指令设计一味追求极端性能引入大量硬件复杂度和不可预测的排除异常行为最后内核用起来会非常别扭反而拖累整个软件生态的落地。IPADS 的做法之所以有说服力在于他们同时明白软件如何消费这些指令和硬件如何生产这些指令能够在性能和可编程性之间找准那条让大家都接受的平衡线。4. 常见问题与排查技巧实录4.1 RISC-V 自定义扩展和高频指令之间编码冲突是怎么解决的RISC-V 指令编码里有相当一部分空间是留给自定义扩展的比如一些custom-0到custom-3的 opcode 段。很多人做私有加速器的时候图省事会直接扔进 custom 段反正别人芯片也实现不了。但如果你的扩展想抱上标准扩展的大腿天然就要面对标准扩展占用了哪些位域、哪些位被预留、哪些位必须保持全0或者全1这些约束。我遇过最头疼的情况是两个扩展都想用同一类 opcode 的低位字段做不同功能结果在混合场景下直接产生指令语义漂移模拟器能过RTL 仿真就挂。排查这类问题最有效的办法是写一个指令重复检测脚本把目标扩展的编码表和已纳入标准的扩展表做交叉比对。或者更简单点直接在 QEMU 里把指令解码表打印出来看有没有重码。如果发现重码第一选择不是换 opcode而是先去 RISC-V 基金会官网查最新 spec 中的 reserved encoding 表看看这个位置是不是已经被将来的扩展预留。我当年就吃过亏图省事占了一个随手选的位段结果那年标准新增了一个扩展恰好把位段重叠了后面为了兼容差点推倒重来。对 IPADS 这么复杂的扩展来说编码空间的规划一定经过了严格论证。尤其涉及系统软件场景的时候新扩展往往需要与 H 扩展、S 扩展supervisor 模式相关交互很多 CSR 地址和指令位域在现有规范中已是敏感区。能在这些约束之间游刃有余说明他们前期做了大量功课。4.2 QEMU 里验证过的行为为什么放到真实核上还是翻车新指令集扩展开发过程中最容易踩的一个大坑是模拟器过拟合。QEMU 里实现一个扩展通常只需要在decode阶段加入指令匹配然后在translate阶段生成对应的 TCG 中间码就算能跑了。但真实核上的执行路径完全不一样有流水线冒险、TLB 命中失败、页表遍历、缓存一致性、异常优先级等等。经常出现的情况是QEMU 里跑 Linux 引导、跑应用全部正常一放到 FPGA 原型或者刚流片回来的芯片上系统随机崩溃dmesg 里全是莫名奇妙的 page fault 或者 illegal instruction。这种翻车大多数时候都是指令语义在特殊异常路径上没定义清楚。我的排查建议是先在 QEMU 里刻意注入各种异常清空 TLB、制造页错误、打一个和读取 CSR 并发的中断把这条新指令在异常路径上的表现全部列出来再拿 RTL 仿真的 trace 去逐条比对。这种做法比单纯靠运气撞 bug 高效得多。另外Linux 内核里启用新扩展时必须要在struct cpuinfo_riscv和elf_hwcap里把特性位正确暴露出来否则驱动或者运行时库在用户态检测不到能力会直接拒绝使用扩展指令性能立刻回到原始状态。很多团队验证完硬件就收工没认真做内核特性标记最后芯片发布出来用户态根本没法调用新能力这种事在商业公司里我没少见。4.3 普通开发者现在可以为这类标准扩展做哪些准备每次看到指令集扩展写入标准的新闻很多人第一反应是跟我没关系我又不能改架构。但实际上这类标准扩展对整个软件生态的影响会比想象中来得更早。通常规范冻结后GCC/LLVM 在下一个版本周期就会加入汇编支持和内建函数QEMU 会同步合入实现Linux 内核的特权规范也会跟进。这时候如果你维护用户态程序可以提前用__riscv_XX这类宏来检测 CPU 能力在支持新扩展的机器上走快速路径在不支持的机器上回退到通用实现这是最快速享受扩展红利的方法。对想做 RISC-V CPU 设计的人我建议直接去读标准扩展文档原文重点关注异常优先级和与已有扩展的组合语义这两节因为这两块最容易流露出真实设计难度。光看每条指令的助记符和功能描述会觉得自己什么都懂了一遇到松耦合、弱一致性场景立刻露馅。对做 OS/驱动的人建议尽早跑一遍 QEMU 上带新扩展的 Linux 内核看看启动日志里 CPU 特性的变化至少把CONFIG_RISCV_ISA_XX这类 kconfig 编译开关的含义弄清楚。标准扩展进来之后内核里一般会有一批以 ISA 扩展为后缀的.config选项和.S汇编片段这些是最直观的学习材料。我现在看一个新的扩展第一件事就是去翻 Linux 主线里有没有相关的 patch看到 patch 里对alternative的使用方式基本就能猜到这个扩展在高频路径上的优化思路了。留在最后的一点个人体会我最初关注 RISC-V 指令集扩展完全是出于验证工作的需要觉得多看几份 spec 能少踩几个汇编语义的坑。但慢慢做下来我发现指令集扩展其实是整个 RISC-V 生态里最有意思的软件与硬件交界处。一个方案能被国际标准采纳表面上赢在指令编码和性能数据实际上赢在它有没有真正理解操作系统要什么、工具链要什么、最终用户要什么。这也是我特别看重 IPADS 这类做系统的团队来主导扩展提案的原因——他们手里有的是真实负载和真实内核代码而不是只有架构师拍脑袋想出来的理想场景。如果你也正好在关注 RISC-V CPU 设计或者底层软件栈我建议不要只盯着主核性能多看看这些正在标准化的扩展是怎么设计的。能把这些扩展的来龙去脉吃透你对软硬件协同设计的理解绝对会上升一个层次。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价