跳到主要内容

JEP 315:改进 Aarch64 内在函数

概括

改进现有的字符串和数组内在函数,并java.lang.Math在 AArch64 处理器上为 sin、cos 和 log 函数实现新的内在函数。

非目标

  • 与其他架构的性能进行比较和匹配
  • 仅在单个 ARM64 架构实现上调整通用 AArch64 端口内在函数以获得最佳性能
  • ARM CPU 端口的端口内在函数

动机

专门的 CPU 架构特定代码模式可提高用户应用程序和基准测试的性能。

描述

内部函数用于利用特定于 CPU 体系结构的汇编代码来执行,而不是针对给定方法执行通用 Java 代码,以提高性能。虽然大多数内在函数已经在 AArch64 端口中实现,但java.lang.Math仍然缺少以下方法的优化内在函数:

  • sin(正弦三角函数)
  • cos(余弦三角函数)
  • log(数字的对数)

该 JEP 旨在通过为这些方法实现优化的内在函数来弥补这一差距。

同时,虽然大多数内在函数已经在 AArch64 端口中实现,但某些内在函数的当前实现可能不是最佳的。具体来说,AArch64 架构的一些内在函数可能受益于软件预取指令、内存地址对齐、多流水线 CPU 的指令放置以及用更快的指令模式或 SIMD 指令替换某些指令模式。

这包括(但不限于)String::compareTo、、、、、、、、以及各种String::indexOf校验和计算等典型操作。StringCoding::hasNegatives``Arrays::equals``StringUTF16::compress``StringLatin1::inflate

根据内在算法、最常见的内在用例和 CPU 细节,可以考虑以下更改:

  • 使用ARM NEON指令集。此类代码(如果将创建任何代码)将被放置在一个标志(例如UseSIMDForMemoryOps)下,以防现有算法具有非 NEON 版本。
  • 使用预取提示指令 (PRFM)。该指令的效果取决于多种因素,例如 CPU 硬件预取器的存在及其功能、CPU/内存时钟比、内存控制器细节以及特定算法需求。
  • 对指令重新排序并减少数据依赖性,以在可能的情况下允许乱序执行。
  • 如果需要,请避免未对齐的内存访问。某些 CPU 实现在跨 16 字节边界、dcache 行边界发出加载/存储指令时会施加惩罚,或者对不同的加载/存储指令具有不同的最佳对齐方式(例如,请参阅 Cortex A53 指南)。如果内在函数的对齐版本不会减慢与对齐无关的 CPU 上的代码执行速度,那么改进地址对齐可能会有益于帮助那些确实有一些惩罚的 CPU,前提是它不会显着增加代码复杂性。

测试

  • 将使用 JMH 基准测试在 Cavium ThunderX、ThunderX2 和 Cortex A53 硬件上测试内在性能。
  • 将使用jtreg测试套件测试功能正确性。如果现有测试库不能提供足够的覆盖范围,可能会创建额外的测试。

风险和假设

  • 我们将努力实现 AArch64 内在函数的最佳性能通用版本。如果这是不可能的,则可能需要为给定硬件供应商编写专用版本的内在函数。
  • 不可能对所有 AArch64 硬件变体执行测试和性能测量。如果在提交补丁供审核时他们认为有必要,我们将依靠 OpenJDK 社区对我们目前没有内部的硬件进行测试。
  • 此 JEP 范围内的内在函数是特定于 CPU 架构的,因此更改它们不会影响共享的 HotSpot 代码。