RFR: 8298244: AArch64: Optimize vector implementation of AddReduction for floating point

Fei Gao fgao at openjdk.org
Wed Dec 14 07:24:16 UTC 2022


The patch optimizes floating-point AddReduction for Vector API on NEON via faddp instructions [1].

Take AddReductionVF with 128-bit as an example.

Here is the assembly code before the patch:

fadd    s18, s17, s16
mov     v19.s[0], v16.s[1]
fadd    s18, s18, s19
mov     v19.s[0], v16.s[2]
fadd    s18, s18, s19
mov     v19.s[0], v16.s[3]
fadd    s18, s18, s19


Here is the assembly code after the patch:

faddp   v19.4s, v16.4s, v16.4s
faddp   s18, v19.2s
fadd    s18, s18, s17


As we can see, the patch adds all vector elements via faddp instructions and then adds beginning value, which is different from the old code, i.e., adding vector elements sequentially from beginning to end. It helps reduce four instructions for each AddReductionVF.

But it may concern us that the patch will cause precision loss and generate incorrect results if superword vectorizes these java operations, because Java specifies a clear standard about precision for floating-point add reduction, which requires that we must add vector elements sequentially from beginning to end. Fortunately, we can enjoy the benefit but don't need to pay for the precision loss. Here are the reasons:

1. [JDK-8275275](https://bugs.openjdk.org/browse/JDK-8275275) disabled AddReductionVF/D for superword on NEON since no direct NEON instructions support them and, consequently, it's not profitable to auto-vectorize them. So, the vector implementation of these two vector nodes is only used by Vector API.

2. Vector API relaxes the requirement for floating-point precision of `ADD` [2]. "The result of such an operation is a function both of the input values (vector and mask) as well as the order of the scalar operations applied to combine lane values. In such cases the order is intentionally not defined." "If the platform supports a vector instruction to add or multiply all values in the vector, or if there is some other efficient machine code sequence, then the JVM has the option of generating this machine code." To sum up, Vector API allows us to add all vector elements in an arbitrary order and then add the beginning value, to generate optimal machine code.

Tier 1~3 passed with no new failures on Linux AArch64 platform.

Here is the perf data of jmh benchmark [3] for the patch:

Benchmark                                      size  Mode  Cnt   Before      After          Units
Double128Vector.addReduction   1024  thrpt     5    2167.146   2717.873   ops/ms
Float128Vector.addReduction       1024  thrpt     5    1706.253   4890.909   ops/ms
Float64Vector.addReduction         1024  thrpt     5    1907.425   2732.577   ops/ms

[1] https://developer.arm.com/documentation/ddi0602/2022-06/SIMD-FP-Instructions/FADDP--scalar---Floating-point-Add-Pair-of-elements--scalar--
     https://developer.arm.com/documentation/ddi0602/2022-06/SIMD-FP-Instructions/FADDP--vector---Floating-point-Add-Pairwise--vector--
[2] https://docs.oracle.com/en/java/javase/19/docs/api/jdk.incubator.vector/jdk/incubator/vector/VectorOperators.html#fp_assoc
[3] https://github.com/openjdk/panama-vector/blob/2aade73adeabdf6a924136b17fd96ccc95c1d160/test/micro/org/openjdk/bench/jdk/incubator/vector/operation/Float128Vector.java#L316
     https://github.com/openjdk/panama-vector/blob/2aade73adeabdf6a924136b17fd96ccc95c1d160/test/micro/org/openjdk/bench/jdk/incubator/vector/operation/Float64Vector.java#L316
     https://github.com/openjdk/panama-vector/blob/2aade73adeabdf6a924136b17fd96ccc95c1d160/test/micro/org/openjdk/bench/jdk/incubator/vector/operation/Double128Vector.java#L316

-------------

Commit messages:
 - 8298244: AArch64: Optimize vector implementation of AddReduction for floating point

Changes: https://git.openjdk.org/jdk/pull/11663/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11663&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8298244
  Stats: 508 lines in 5 files changed: 40 ins; 16 del; 452 mod
  Patch: https://git.openjdk.org/jdk/pull/11663.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/11663/head:pull/11663

PR: https://git.openjdk.org/jdk/pull/11663


More information about the hotspot-compiler-dev mailing list