On Thu, 2 Jul 2026 12:42:00 GMT, Ehsan Behrangi <[email protected]> wrote:
>> 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? > > Yes. I implemented that version for comparison. > > I have two standalone AArch64/NEON P16 implementations: > > reduce_loop: performs the horizontal reduction inside every 16-byte iteration. > reduce_end: keeps 16 logical accumulators (four NEON vectors) across the loop > and performs a single reduction after processing all blocks (AArch64 current > stub is a smarter(less vector registers) implementation of this algorithm > too). > > For this experiment, both implementations assume: > > input length is a multiple of 16, > no tail handling, > seed = 0. > > On my test system, both implementations produce the same result as the scalar > reference for the tested lengths under those assumptions. > > At 64 KB, I measured: > > reduce_loop: 0.0976 ns/byte > reduce_end : 0.1316 ns/byte > > reduce_loop was consistently faster across all tested lengths from 16 bytes > up to 64 KB. > > I've also included a small benchmark driver and build/run instructions so > others can reproduce the comparison: > [hash.zip](https://github.com/user-attachments/files/29598153/hash.zip) > > g++ -O3 -march=armv8-a -o hash_bench \ > driver.cpp \ > hash_jdk_neon_reduce_loop.S \ > hash_jdk_neon_reduce_end.S > ./hash_bench > > This is detailed output: > === Correctness display only; mismatch is OK for this experiment === > len= 16 scalar=0xCAD5BD38 loop=0xCAD5BD38 end=0xCAD5BD38 > len= 32 scalar=0x20787A70 loop=0x20787A70 end=0x20787A70 > len= 64 scalar=0xB196B3E0 loop=0xB196B3E0 end=0xB196B3E0 > len= 128 scalar=0x5E42E8C0 loop=0x5E42E8C0 end=0x5E42E8C0 > len= 256 scalar=0xF24DEF80 loop=0xF24DEF80 end=0xF24DEF80 > len= 512 scalar=0x07ABDF00 loop=0x07ABDF00 end=0x07ABDF00 > len= 1024 scalar=0x9B97BE00 loop=0x9B97BE00 end=0x9B97BE00 > len= 4096 scalar=0x945EF800 loop=0x945EF800 end=0x945EF800 > len=16384 scalar=0xB17BE000 loop=0xB17BE000 end=0xB17BE000 > len=65536 scalar=0xC5EF8000 loop=0xC5EF8000 end=0xC5EF8000 > > #=== Performance === > > Implementation len iters ns/call ns/byte MB/s > -------------------------------------------------------------------------------- > scalar 16 50000 7.03 0.4397 2274.46 > reduce_loop 16 50000 2.44 0.1526 6553.29 > reduce_end 16 50000 3.05 0.1908 5240.16 > > scalar 32 50000 16.99 0.5309 1883.59 > reduce_loop 32 50000 3.97 0.1241 8060.90 > reduce_end 32 50000 4... OK, I'll buy that. Performance looks good. I think we need a comment that explains this performance, in brief, to save future maintainers' time. Feel free to include a link to this conversation. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/31674#discussion_r3536652264
