[ 导语 ] 2022年3月22日,JDK18正式对外发布。据Oracle官方公告[1],腾讯Kona 蝉联JDK18中国企业贡献排名第一,连续四次对OpenJDK贡献全国排名第一(JDK15~18)[1][2][3][4]。本文将介绍Kona在高性能计算引擎方面对OpenJDK社区的贡献。
▍Kona:连续四次全国冠军,综合贡献全国第一
Kona是腾讯基于OpenJDK研发的JDK产品,Kona JDK完全免费,并提供长期支持,所发版本均通过腾讯内部和云上超大规模应用验证,欢迎下载使用。
- 2019年:首次对外开源
TencentKona-8 :
https://github.com/Tencent/TencentKona-8;
- 2021年:开源两个版本
TencentKona-11:
https://github.com/Tencent/TencentKona-11;
TencentKona-17:
https://github.com/Tencent/TencentKona-17。
2022年3月22日,JDK18对外发布。据Oracle官方公告 [1],腾讯Kona 蝉联JDK18中国企业贡献排名第一,连续四次对OpenJDK贡献全国第一(JDK15~18)[1][2][3][4]。值得注意的是,官方还首次公布了OpenJDK的综合贡献排名(JDK11~18)。结果表明,腾讯Kona的综合贡献全国第一,世界第五(紧随Oracle、RedHat、SAP和Google四大巨头之后)[5]。
随着业务规模和复杂度的不断增加,我司成立了专门的JVM研发团队并内部协同了TencentKonaJDKOteam (含多位OpenJDK社区reviewer/committer/author),负责Kona JDK的研发和维护。在解决公司内部迫切需求的同时,团队高度重视对外开源,参与了包括JDK、Panama和Loom等OpenJDK社区重要项目。
在刚刚发布的JDK18中,Kona向OpenJDK社区贡献了约50个Patch,涉及HotSpot虚拟机内核(JIT、Runtime和GC)、SVC、Core Libraries和Infrastructure等领域。为解决Java/JVM数据科学场景性能问题,Kona针对广告模型训练、OLAP引擎等关键业务场景的需求,研发了面向机器学习和大数据系统的高性能Java计算引擎,并在实际业务场景中落地和应用。目前,已经贡献到OpenJDK社区的高性能Java计算引擎研发成果包括:
- 1)Vector API
- 2)自动向量化
- 3)数学库优化
本文介绍Kona在上述三个方面的代表性工作,并在最后进行小结。
▍Vector API:社区核心开发者
根据JDK18的release notes [6],继JDK16和JDK17之后,Vector API第三次作为重点打造的JEP特性在JDK新版本中发布。如图1所示,Kona 从2020年开始参与Vector API开源贡献,到2021年团队成员被提名为Vector API 项目的Committer [7],再到2022年正式成为JDK18 Vector API全球十大署名贡献者之一 [8],标志着Kona正式跻身Vector API开源社区核心开发者之列。Vector API是一组通用Java编程接口,通过Java虚拟机生成SIMD向量指令来加速性能,具有编程方便、效果显著和跨平台等特点。根据官方公布的数据 [9],Vector API对矩阵运算等典型数据科学场景可以达到2~16倍的性能加速效果。
图1 Kona 参与Vector API开源贡献历程
Kona在生产实践中首次适配并完善了Vector API对AVX512高性能向量指令的翻译,贡献了20多个向量编译器相关patch。Kona解决了Vector API长期无法应用于生产实践的痛点,使得Vector API在广告训练和大数据OLAP引擎等实际业务系统中落地成为可能,并为后期产业界的规模化应用蹚平了道路。
在性能优化方面,Kona优化了SVML(Short Vector Math Library)向量加速能力。SVML是一款高性能向量优化数学库,用于进一步加速Vector API的向量数学运算。受向量编译器历史遗留的至少需要两个double才能向量化的限制,最初的SVML无法对单个double数据进行加速。但实际业务基于单个double的数学运算也很常见,加速需求也很迫切。经过反复分析和实验,Kona突破了向量编译器强制要求至少两个double的限制,巧妙地将单个double视为64位向量进行SVML加速。如图2所示,优化后大多数算子的性能提升为优化前的2~3倍,个别高达9~10倍。
此外,Kona还解决了SVML幂运算算子性能下降问题。通过实验,我们发现该算子仅在AVX512机器上有加速效果,在其它机型上反而导致约27%的性能下降。于是优化了SVML对幂运算的加速策略,当且仅当在AVX512机型上才启用,从而解决了SVML性能下降问题。Kona也因上述两个优化成为OpenJDK社区SVML全球三大贡献者之一(另外两位是Intel和Oracle)。
图2 SVML向量加速优化
▍自动向量化:二维数组自动向量化
自动向量化是Java虚拟机在程序运行期间,将源程序自动编译为向量指令的优化技术。和Vector API相比,自动向量化无需修改源代码,具有智能高效的特点,尤其适用于源代码无法获取、修改的场景。但自动向量化非常脆弱,对程序员的编程约束很多,稍有不慎便自动向量化失败。因此,增强自动向量化能力,也是现代高性能计算引擎研发的重点。
图3展示了Kona优化JDK自动向量化的一个真实案例。在对公司广告模型训练的矩阵加法算子,如图3(a)所示,进行性能分析时,发现矩阵加法算子经过JDK编译之后,核心循环竟然没有被自动向量化,仅生成了如图3(b)所示的标量指令。我们对此非常惊讶:图3(a)为经典的矩阵操作编程模式,仅包含简单的加法操作,并不存在导致自动向量化失败的因素。随后,我们实验了更简单的矩阵拷贝操作,发现JDK还是无法自动向量化。但是,如果将图3(a)中的二维数组,换成一维数组,JDK是可以自动向量化的。于是,我们确信发现了一个二维数组自动向量化的性能Bug。经过分析,确认自动向量化失败的原因是,向量编译引擎对二维数组存在过早退出自动向量化流程的缺陷。该缺陷在x86机器上对于NUM < 69的二维数组100% 复现。机理清楚后,Kona向OpenJDK社区提交了修复patch,社区专家对本问题的发现和修复给予了高度评价 [10]。优化后,图3(a)中的矩阵加法算子自动向量化成功,生成如图3(c)的向量指令,在x86上获得约1.7x的性能加速效果。
图3 基于二维数组的矩阵算子自动向量优化
▍数学库优化:pow(x, 0.5)加速
除向量增强外,JDK数学库也是影响计算引擎性能的关键因素。在底层数学库优化方面,Kona优化了数学算子pow(x, 0.5)的性能。这项工作的背景是我们在分析广告模型训练代码时,发现业务代码存在调用pow(x, 0.5)计算x的平方根的情形。通过对JDK编译结果的观察,发现pow(x, 0.5)并未生成硬件直接支持的开方指令sqrt来实现。但如果编码时将pow(x, 0.5)换成sqrt(x),则JDK可以编译生成高效的开方指令。虽然x的0.5次方和x的开方在数学上等价,但是现代CPU硬件直接支持的开方指令性能明显更高。于是就有两种优化方案,一种是修改业务代码,将所有pow(x, 0.5)替换为sqrt(x);另一种是优化JDK,将算子pow(x, 0.5)的翻译在JDK中自动转换为使用开方指令sqrt(x)来计算。显然,优化JDK的方案是最优的,不仅可以避免对业务代码的修改,还能一劳永逸、彻底解决pow(x, 0.5)算子计算性能低下的问题。因此,Kona选择了优化JDK。
图4展示了pow(x, 0.5)算子优化的机理。如图4(a)所示,优化前,JDK三大执行引擎均调用Intel高性能汇编数学库完成计算。所以,首先是优化Intel的高性能数学库,直接将x的0.5次方替换为开方指令。进一步地,Kona还优化了C2编译器,通过优化编译生成的IR,生成SqrtD的中间表示节点(如图4(b)所示),避免了对Intel数学库的调用开销。最终的优化实现如图4(c)所示。优化后,该算子的性能提升了7~16倍。
图4 pow(x, 0.5)性能加速
需要特别注意的是,从数学角度理论分析,将pow(x, 0.5)替换成sqrt(x)是等价的。但是,在编译器的工程实现中,上述直接替换却是错误的。根据IEEE754规范,当x的值为-0.0和负无穷大时,两者在计算机中返回的结果并不相等!规定的返回值如图5所示。注意在计算机的二进制表示中,0.0和-0.0是两个不同的浮点数结果。因此,优化时绝对不能将pow(x, 0.5)无条件替换为sqrt(x)。Kona贡献的方案是:仅当x > 0时才替换,如图4(c)所示。故在编译器优化时,务必注意数学理论与工程实践的差异。
图5 IEEE754规范中pow(x, 0.5) != sqrt(x) 的情形
▍小结
从JDK15开始,Kona已连续四次获得OpenJDK贡献全国第一。并且,在今年官方首次公布的OpenJDK综合贡献排行榜中,Kona也位居全国第一。为解决Java/JVM数据科学场景性能问题,Kona针对广告模型训练、OLAP引擎等关键业务场景的需求,持续研发面向机器学习、大数据的高性能Java计算引擎,并向OpenJDK社区贡献了Vector API、自动向量化、数学库优化等代表性成果。除JDK项目外,Kona对Loom等项目也有比较突出的贡献。未来,Kona将继续深度参与社区建设,积极拥抱开源。 最后,欢迎各位优秀的开发者加入腾讯大数据编译器团队!
▍作者介绍
Jiefu:腾讯高级工程师,OpenJDK Reviewer
附:
Kona8 :https://github.com/Tencent/TencentKona-8,
Kona11:https://github.com/Tencent/TencentKona-11,
Kona17:https://github.com/Tencent/TencentKona-17。
注:
[1] JDK18贡献排名:https://twitter.com/OpenJDK/status/1506283035213406208
[2] JDK15官方公告:
https://blogs.oracle.com/java/post/the-arrival-of-java-15
[3] JDK16官方公告:
https://blogs.oracle.com/java/post/the-arrival-of-java-16
[4] JDK17官方公告:
https://blogs.oracle.com/java/post/announcing-java17
[5] 综合贡献排名(JDK11~18):
https://blogs.oracle.com/java/post/the-arrival-of-java-18
[6] JDK18 release notes:https://jdk.java.net/18/release-notes
[7] Vector API项目Committer提名:https://mail.openjdk.java.net/pipermail/panama-dev/2021-September/014910.html
[8] JDK18 Vector API新特性patch:https://github.com/openjdk/jdk/commit/a59c9b2ac277d6ff6be1700d91ff389f137e61ca
[9] Vector API官方性能数据:
https://static.rainfocus.com/oracle/oow19/sess/1553206138311001UVQD/PF/OCO19-Vector_API_1569011845017001idU3.pdf
[10] 二维数组自动向量优化:https://github.com/openjdk/jdk/pull/6933