| JDK 21 | 
|---|
| 21 b24Fixed | 
| Blocks :   | |
| Relates :   | |
| Relates :   | |
| Relates :   | |
| Relates :   | |
| Relates :   | |
| Relates :   | |
| Relates :   | 
Currently, we do all reductions inside the loop. This makes sense for floating-point Add and Mul, where the order of reduction must be strictly linear, so as not to violate IEEE specification (basically the rounding would be ever so slightly different, and lead to wrong results).
Pseudocode:
acc = init
For (i ...) {
   vec = "some vector ops"; // vec holds vector of results from this iteration
   vector_reduction(vec, acc); // reduces vector vec into scalar accumulator acc
}
// use acc
However, in integer-reductions, and some floating-point reductions that do not require the linear order (Min / Max), we can do better. We can use a vector-accumulator in the loop, and do the reduction on this vector only after the loop. This should significantly reduce the work per loop iteration.
v_acc = scalar_to_vector(init); // depends on reduction op how we would do this
For (i ...) {
   vec = "some vector ops"; // vec holds vector of results from this iteration
   v_acc = vector_elememt_wise_reduction(v_acc, vec);
}
acc = vector_reduction(v_acc);
// use acc
Note: we already have different reduction implementations.
We already do a "recursive folding" for ints (C2_MacroAssembler::reduce8I), and a "linear folding" for floats (C2_MacroAssembler::reduce8F).
https://github.com/openjdk/jdk/blob/db1b48ef3bb4f8f0fbb6879200c0655b7fe006eb/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp#L1895-L1941
https://github.com/openjdk/jdk/blob/db1b48ef3bb4f8f0fbb6879200c0655b7fe006eb/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp#L2096-L2120
I found this while working on JDK-8302139, where I implemented an IR test for SuperWord reductions, and checked out the generated code.
| 
 |