JDK-8344085 : C2 SuperWord: improve vectorization for small loop iteration count
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 24
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2024-11-13
  • Updated: 2024-11-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Relates :  
Relates :  
Description
SuperWord is relatively well suited for high iteration count, where we spend most time in the super-unrolled main-loop. This gives us good throughput.

But for small iteration count, there are some issues:
- We align the loop in pre-loop. This can be up to vector-length (number of elements in vector) many iterations.
- Then we check at the zero-trip guard of the main-loop if we have enough iterations left to enter the super-unrolled main-loop. This would require that we have super-unroll-factor * vector-length many iterations left. If we have fewer, we directly go into the post-loop and never enter vectorized code at all.
- This is why we have filed JDK-8307084: if we don't have enough iterations for the super-unrolled main-loop, we should at least enter the vectorized post-loop. That has lower throughput, but is still good for not just cleanup after the main-loop but also for small iteration counts where we cannot use the main-loop.

One idea was JDK-8308994. That may work for some platforms - though it is maybe not worth the complexity. Still, they gathered some interesting data in the plots / benchmarks, see:
https://github.com/openjdk/jdk/pull/14581
Look at the saw-tooth plots it produces: we see that there are different phases.

We should have such a nice benchmark, so that we can experiment well.

Another issue is the pre-loop: it aligns the vectors for the main-loop. But it seems that on modern CPU's such alignment is not as performance relevant as on older CPU's. So here we really waste some possible iterations we might need to enter vectorized loops.
Comments
I think dropping the pre-loop is reasonable. I think clang also does not introduce a pre-loop: https://godbolt.org/z/Whf38edj9 Another benefit of dropping the pre-loop is that it is then easier to reason about the trip count of the main loop. Currently, we cannot fully unroll this loop after vectorization: for (int i = 0; i < 64; i++) { a[i] = b[i]; } Or eliminate the post-loop in these kinds of loop: for (int i = 0; i < x * 64; i++) { a[i] = b[i]; }
16-11-2024