RFR: 8298244: AArch64: Optimize vector implementation of AddReduction for floating point [v2]
Andrew Haley
aph at openjdk.org
Thu Dec 15 12:07:05 UTC 2022
On Thu, 15 Dec 2022 09:39:24 GMT, Fei Gao <fgao at openjdk.org> wrote:
>> 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
>
> Fei Gao has updated the pull request incrementally with one additional commit since the last revision:
>
> Update the comments
Marked as reviewed by aph (Reviewer).
-------------
PR: https://git.openjdk.org/jdk/pull/11663
More information about the hotspot-compiler-dev
mailing list