From 22a840aa9bfbabd7b4daf5c5f9852e1c68908d03 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Wed, 19 Apr 2023 16:41:37 -0700 Subject: [PATCH] runtime: mix a bit more in arm64 hash function We really need 3 mix steps between the data being hashed and the output. One mix can only spread a 1 bit change to 32 bits. The second mix can spread to all 128 bits, but the spread is not complete. A third mix spreads out ~evenly to all 128 bits. The amd64 version has 3 mix steps. Fixes #59643 Change-Id: I54ad8686ca42bcffb6d0ec3779d27af682cc96e9 Reviewed-on: https://go-review.googlesource.com/c/go/+/486616 Run-TryBot: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot --- src/runtime/asm_arm64.s | 1 + src/runtime/hash_test.go | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s index ef70970f775..143ea38fbeb 100644 --- a/src/runtime/asm_arm64.s +++ b/src/runtime/asm_arm64.s @@ -611,6 +611,7 @@ done: AESE V0.B16, V2.B16 AESMC V2.B16, V2.B16 AESE V0.B16, V2.B16 + AESMC V2.B16, V2.B16 VMOV V2.D[0], R0 RET diff --git a/src/runtime/hash_test.go b/src/runtime/hash_test.go index d4a2b3f6bb5..099bf511295 100644 --- a/src/runtime/hash_test.go +++ b/src/runtime/hash_test.go @@ -775,8 +775,11 @@ func TestCollisions(t *testing.T) { a[j] = byte(n >> 8) m[uint16(BytesHash(a[:], 0))] = struct{}{} } - if len(m) <= 1<<15 { - t.Errorf("too many collisions i=%d j=%d outputs=%d out of 65536\n", i, j, len(m)) + // N balls in N bins, for N=65536 + avg := 41427 + stdDev := 123 + if len(m) < avg-40*stdDev || len(m) > avg+40*stdDev { + t.Errorf("bad number of collisions i=%d j=%d outputs=%d out of 65536\n", i, j, len(m)) } } }