Tencent Kona:OpenJDK贡献全国四连冠,赋能数据科学计算加速

2022-03-31 11:40:12 浏览数 (1)

[ 导语 ] 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

0 人点赞