OpenJDK 的 RISC-V 生态实践:从版本反合到 C2 后端优化

简介: 为什么在 RISC-V 生态中谈 OpenJDK?

编者按:随着 RISC-V 向服务器级芯片演进,Java 作为服务端生态的核心语言,其运行时 OpenJDK 在新架构上的成熟度直接决定着 Java 服务落地的广度与深度。中兴通讯作为龙蜥社区副理事长单位,围绕 RISC-V 架构下 Java 基础软件栈的完善持续投入,重点推进 OpenJDK 在编译器后端、向量化能力和长期支持版本适配等方向的技术实践,并将相关工程经验与优化成果反馈到社区生态中,助力龙蜥社区推动 RISC-V 编译器相关技术的持续演进与规模化落地。在RISC-V 编译器生态和性能优化 MeetUp上,来自中兴通讯的张诗烩分享了《OpenJDK RISC-V 生态实践》主题演讲。他围绕 OpenJDK 在 RISC-V 架构上的工程化实践展开,重点介绍了 OpenJDK master 分支中 RISC-V 相关改进反合到 OpenJDK 21 的过程,并结合当前针对 RVV 后端冗余 vset 指令的优化工作,分析了 RISC-V 向量化代码生成中的性能问题与改进思路。以下为本次演讲全文。

为什么在 RISC-V 生态中谈 OpenJDK?

在正式展开技术细节之前,我想先回答一个问题:为什么我们需要在 RISC-V 生态里专门讨论 OpenJDK?

我认为主要有两个方面的原因。一方面,当前 RISC-V 正走向服务器级别的芯片,而 Java 在服务器生态领域里占据着非常重要的作用——企业级中间件、大数据平台、微服务框架背后几乎都是 JVM 在支撑。OpenJDK 在 RISC-V 上的成熟度,将直接影响 Java 服务生态在该架构上的落地。另一方面,OpenJDK 本身也是一个非常综合的软件栈,集成了 JIT 编译器、垃圾回收器、向量化库、JNI 原生接口等大量底层能力。如果 OpenJDK 能在 RISC-V 架构上高性能地运行,也从一定层面反映出 RISC-V 生态的成熟度。它既是一个“用户”,也是一个“标尺”。

从版本演进的角度看,OpenJDK 对 RISC-V 的支持程度呈现出一个逐步上升的趋势。对于 OpenJDK 8、OpenJDK 11 早期 LTS 版本,上游的支持程度非常有限,主要依靠下游厂商的反合与维护来推进。真正的转折点发生在 OpenJDK 19 的 JEP 422——从这一节点开始,RISC-V 正式进入 OpenJDK 上游主线。当前 OpenJDK 主线已基本实现对 RVA23 Profile 的支持,并合入了大量向量、加解密优化等后端能力。

不过,当前我们仍然面临一个现实矛盾:主线分支对 RISC-V 的支持在不断演进,但大量用户仍在使用存量的 LTS 版本,这些版本对 RISC-V 的支持远远不够,而这将是 OpenJDK 在 RISC-V 生态上必须直面的挑战。

当前问题:从“支持可用”到“性能成熟”

从上述介绍可以看到,OpenJDK 主线已经完成了对 RISC-V 的基本支持。所以当下的问题已经从“支持可用”到“性能成熟”。我认为至少有三个方面的问题有待解决:

第一,LTS 版本的反合与维护。目前有大量用户仍在使用 OpenJDK 8、OpenJDK 11 等旧版本,如何为这些用户提供一个高性能、可维护的 OpenJDK 版本,将直接决定 OpenJDK 在 RISC-V 上的使用范围。

第二,后端优化,尤其是 C2 编译器的优化。 它决定了 OpenJDK 在 RISC-V 上的性能能否与 x86、Arm 等主流成熟架构对齐。

第三,Native 库的适配优化。 许多 Java 应用底层依赖 Native 库(比如 OpenSSL、FFmpeg 等),这些库在 RISC-V 上的适配质量,会直接决定 Java 应用在 RISC-V 架构上的迁移成本。

我们在 OpenJDK 生态上做的实际工作

中兴通讯在 OpenJDK 做的工作可以分为两个方面:OpenJDK 21 反合与主线分支的优化推进。在 OpenJDK 21 的反合工作中,我们分析筛选出主线中 40 余条关键 PR,共计一万多行代码合入到 OpenJDK 21,并完成了反合代码的功能与性能验证。SPECjvm 2008 的测试结果显示,反合后整体性能提升了约 4 %。另一方面,我们也在积极推进 OpenJDK 主线分支的优化。目前共计开发了十多项特性,涵盖:

  • 扩展集补齐:让 OpenJDK 能调用更多 RISC-V 指令集能力;
  • 加解密算法优化:利用 RISC-V 向量扩展加速 SM/AES 等算法;
  • C2 后端优化:包括本文重点分享的冗余 vset 指令消除方案。

SPECjvm 测试结果显示,相比开源版本,我们优化后的版本整体性能提升了约 10%。

深度剖析:如何消除 C2 产生的冗余 vset 指令

下面我将具体介绍中兴通讯在 OpenJDK RISC-V 上做的优化,聚焦于如何消除 C2 编译器产生的冗余 vset 指令。

RISC-V 向量扩展(RVV)采用向量长度无关(VLA)模型,使得同一份向量代码无需针对不同硬件的寄存器长度进行修改即可直接执行。为实现这一特性,RVV 要求在执行向量操作前通过 vset 指令配置执行状态,涵盖元素数量、元素宽度(sew)、寄存器分组(lmul)、掩码及尾部处理策略等参数。

尽管 vset 是向量操作的必要前提,但若被重复配置为相同状态,则会引入不必要的性能开销。例如在汇编序列中,首条 vset 因需初始化向量状态而不可或缺,但后续若出现配置完全相同的 vset 指令,便构成了冗余。

这类冗余指令主要从三个方面损害性能:首先,vset 会更新 vl、vtype 等 CSR 寄存器,冗余调用会频繁制造状态切换边界,干扰流水线调度;其次,作为真实指令,它会占用 fetch、decode、issue 等前端资源,在循环或核心计算上下文中更难隐藏延迟;最后,冗余指令还会拉长循环体代码,降低代码密度并增加 L1 Cache 压力。鉴于上述影响,在编译器层面消除冗余 vset 指令成为优化 RVV 程序性能的关键措施。

在 C2 编译器中,一个简单数字加法循环会被编译成 LoadVectorAddVectorStoreVector 等架构无关的中间表示,经过一系列图优化后,最终匹配到 RISC-V 后端的 MachNode 上,用于发射机器码。这个问题就出现在 MachNode 这一层。

在当前 OpenJDK 的实现中,为了保证每条向量指令都能正确执行,它在每个向量 MachNode 里都调用了一个 vset_helper 函数。这个函数会读取每个向量 MachNode 所需的向量状态配置,然后生成一条匹配的 vset 指令。由于这些 vset_helper 之间缺少统一的状态视图,每个向量 MachNode 都会生成一条 vset,冗余也就此产生。

冗余 vset 指令产生的根源在于编译器缺乏统一的状态视图。为构建这一视图,我们需要在编译器中将 vset 指令的状态显式化表达出来。以下图左侧所示,从 Java 代码到最终机器码的编译流程为例,我们可以从中识别出三个建立 vset 指令显式化的潜在切入点。其中,第一个切入点位于最终机器码发射阶段:在此阶段,编译器能够逐条读取待发射的指令,因此可以顺势记录下每条 vset 指令所配置的状态信息,从而为后续消除冗余奠定基础。第二个切入点可以选择在架构无关的中间表示层(IdealGraph )中进行,通过在该层设计专门的 vset IR 节点,我们便能够利用后续的图优化过程实现状态的有效传播。第三个切入点则位于 MatchNode 层,若在此处插入 vset 的 Match Node 节点,同样可以依托后续的控制流图完成优化。

策略一:在 vset_helper 中记录状态

由于每条 vset 指令最终都要通过 vset_helper 发射,我们可以在其中记录上一次 vset 的状态。如果当前要发射的状态与前一次一致,就跳过发射。本方案的优点是实现非常简单——最初用不到 100 行代码差不多实现了。而它的主要不足是在代码发射阶段,编译器只能以发射顺序看到指令;一旦指令全部进入 code buffer,后续就很难再做调整和修改。

策略二:IdealGraph 层优化

上述提到的第二种方案选择在架构无关的中间表示层( IdealGraph )中实施,即通过插入专门的 vset 节点,借助后续的图优化过程实现状态传播。该方案的优势在于优化介入点较少,且理论上具备最全局的视野,因此能够支持更为复杂的优化策略。然而,其显著缺点是将 RISC-V 特有的向量状态引入了平台无关的 IR 层,这会破坏中间表示的通用性,给后续的整体代码设计与维护带来极大的复杂度。

策略三:MachNode 层优化(最终选择)

在 MachNode 层插入 vset MachNode 节点。由于 MachNode 已经进入了 RISC-V 后端,在这一层做优化不会污染平台无关的 IdealGraph;同时控制流图等信息仍然存在,可以做相对复杂高级的优化。

我们最终选择了这一方案,并围绕显式化的 vset 节点设计了三种去冗余方法:

1. 块内去冗余。让编译器维护一个 currentState,记录当前基本块内的 vset 状态。每当遇到一个 vset 节点,就和 currentState 对比——相同则删除,不同则保留并更新状态。

2. 块间去冗余。为每个基本块配置 inStateoutState 两个状态。inState 描述进入基本块时编译器能确定的 vset 状态,outState 描述该基本块能传递给下一个基本块的状态。只有当所有前驱基本块的 outState 相同且有效时,才把当前基本块的 inState 设为该状态,从而实现基本块间的状态传播。

3. 循环外提。 在 C2 中,一个循环会被编译成“循环边(entry edge)”和“循环体”两部分。循环体会被反复执行,而循环边一般只执行一次。我们把循环体内满足外提条件的 vset 指令提到循环边里——由于循环边和循环体属于两个不同的基本块,后续再用块间去冗余方法就能删除循环体里的冗余 vset

MachNode 层优化验证结果显示,在正确性方面,我们用 JTReg 测试在 QEMU 与真实 RISC-V 硬件环境上跑通了全部相关用例。在性能方面,SPECjvm 及相关 benchmark 测试显示,优化带来了比较明显的性能提升。

总结

RISC-V 生态的成熟不是一家公司的独角戏,而是整个社区持续共建的结果。未来,中兴通讯也将依托龙蜥社区这一开放平台,与广大社区开发者和产业伙伴携手参与 RISC-V 基础软件生态共建,围绕 OpenJDK 编译器优化、版本适配、性能验证和应用迁移等方向沉淀更多实践成果,共同推动 RISC-V Java 软件栈从“可用”走向“好用”,为更多业务场景在新架构上的落地提供支撑。

本次 MeetUp  PPT 、视频回放已上线龙蜥官网,欢迎点击查看:

PPT 下载链接

https://docs.openanolis.cn/document/detail/rpzigrnb

视频回放:

https://openanolis.cn/video/#1658313779883670231

—— 完 ——

相关文章
|
5天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1904 5
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
13天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2493 13
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
13天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max-Preview深度全解析:2.4万亿参数旗舰MoE模型+Token Plan限时优惠完整落地指南
2026年7月,全新旗舰级混合专家大模型Qwen3.8-Max-Preview正式开放抢先体验,作为通义千问Qwen3系列规格最高、综合推理能力顶尖的新一代模型,该模型总参数量达到2.4万亿(2.4T),是当前线上可调用的原生多模态旗舰模型,综合推理水准对标海外顶级Fable 5模型,在复杂工程开发、长文档深度分析、多步骤智能体自治、跨境多语言创作、海量数据挖掘五大高难度业务场景实现跨越式性能提升。
1317 2
|
11天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
1118 2
|
15天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
1343 52
|
11天前
|
自然语言处理 测试技术 API
通义千问Qwen3.8-Max-Preview全功能解析:2.4万亿参数旗舰模型深度使用指南
在大模型技术持续迭代的当下,通义千问推出的Qwen3.8-Max-Preview作为新一代旗舰预览版模型,凭借2.4万亿参数的超大规模、多模态融合能力与全场景适配特性,成为开发者与企业用户探索AI应用的核心工具。该模型采用稀疏混合专家(MoE)架构,是通义千问首个突破万亿参数的多模态模型,可同时处理文本、图像、视频与文档等多种数据形态,在全栈代码开发、复杂逻辑推理、长文档分析与多智能体协作等场景实现跨越式升级。本文将全面拆解Qwen3.8-Max-Preview的核心功能,详解API调用流程与配置方法,覆盖多场景实战技巧,帮助用户快速掌握这款旗舰模型的使用方法,充分释放其性能潜力。
622 2
|
12天前
|
SQL 关系型数据库 MySQL
【2026最新】DBeaver下载、安装、数据库管理一篇搞定(附官网社区版安装包)
DBeaver是一款免费开源的跨平台通用数据库管理工具,支持MySQL、PostgreSQL、SQLite、Oracle等几乎所有主流数据库,无需为每种数据库安装独立客户端,极大提升开发与数据分析效率。

热门文章

最新文章