On Tue, 30 Jun 2026 16:34:38 GMT, Ehsan Behrangi <[email protected]> wrote:
>> src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp line 9315: >> >>> 9313: __ addv(v_block2, Assembler::T4S, v_block2, v_block3); >>> 9314: __ addv(v_block0, Assembler::T4S, v_block0, v_block2); >>> 9315: >> >> This looks like you're doing the final reduction inside the loop, rather >> than leaving it until the end of the loop. But why are you doing that? > > The current organization is intentional. I considered carrying the > lane-position weights across loop iterations, similar to the x86_64 > implementation, as well as the previous AArch64 implementation. > > The previous AArch64 implementation worked well on some cores by creating > multiple smaller multiplication chains to help hide multiply latency for long > arrays. In my measurements on recent Arm Neoverse cores (for example, > Neoverse V2 and N2), reducing each 16-element block to a scalar block hash > and then performing the scalar Horner update exposed more independent work to > the scheduler and produced better performance than carrying vector > accumulators across loop iterations. > > The horizontal reduction is relatively inexpensive on these cores and can > overlap with the vector multiply/add work, making the per-block reduction a > good tradeoff. But what's the point of exposing more independent work to the scheduler, when that work doesn't do anything useful? Do you have the version without the reduction each time so we can compare it on other implementations? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/31674#discussion_r3500563737
