diff --git a/bits_amd64.go b/bits_amd64.go index 2d95b40..5bd6ac7 100644 --- a/bits_amd64.go +++ b/bits_amd64.go @@ -31,12 +31,12 @@ const ( type bitset uint16 func metaMatchH2(m *metadata, h h2) bitset { - b := simd.MatchMetadata((*[16]int8)(m), int8(h)) + b := simd.MatchMetadata((*[groupSize]uint8)(m), uint8(h)) return bitset(b) } func metaMatchEmpty(m *metadata) bitset { - b := simd.MatchMetadata((*[16]int8)(m), empty) + b := simd.MatchMetadata((*[groupSize]uint8)(m), empty) return bitset(b) } diff --git a/bits_test.go b/bits_test.go index b928d55..291d4ae 100644 --- a/bits_test.go +++ b/bits_test.go @@ -26,7 +26,7 @@ import ( func TestMatchMetadata(t *testing.T) { var meta metadata for i := range meta { - meta[i] = int8(i) + meta[i] = uint8(i) } t.Run("metaMatchH2", func(t *testing.T) { for _, x := range meta { @@ -43,7 +43,7 @@ func TestMatchMetadata(t *testing.T) { mask = metaMatchEmpty(&meta) assert.NotZero(t, mask) assert.Equal(t, uint32(i), nextMatch(&mask)) - meta[i] = int8(i) + meta[i] = uint8(i) } }) t.Run("nextMatch", func(t *testing.T) { @@ -54,7 +54,7 @@ func TestMatchMetadata(t *testing.T) { assert.Equal(t, uint32(i), nextMatch(&mask)) } for i := 0; i < len(meta); i += 2 { - meta[i] = int8(42) + meta[i] = uint8(42) } mask = metaMatchH2(&meta, h2(42)) for i := 0; i < len(meta); i += 2 { @@ -66,7 +66,7 @@ func TestMatchMetadata(t *testing.T) { func BenchmarkMatchMetadata(b *testing.B) { var meta metadata for i := range meta { - meta[i] = int8(i) + meta[i] = uint8(i) } var mask bitset for i := 0; i < b.N; i++ { @@ -90,14 +90,13 @@ func nextPow2(x uint32) uint32 { } func TestConstants(t *testing.T) { - c1, c2 := empty, tombstone - assert.Equal(t, byte(0b1000_0000), byte(c1)) - assert.Equal(t, byte(0b1000_0000), reinterpretCast(c1)) - assert.Equal(t, byte(0b1111_1110), byte(c2)) - assert.Equal(t, byte(0b1111_1110), reinterpretCast(c2)) + assert.Equal(t, byte(0b1000_0000), empty) + assert.Equal(t, byte(0b1000_0000), reinterpretCast(empty)) + assert.Equal(t, byte(0b1111_1110), tombstone) + assert.Equal(t, byte(0b1111_1110), reinterpretCast(tombstone)) } -func reinterpretCast(i int8) byte { +func reinterpretCast(i uint8) byte { return *(*byte)(unsafe.Pointer(&i)) } diff --git a/map.go b/map.go index d2b188e..4ed9078 100644 --- a/map.go +++ b/map.go @@ -36,7 +36,7 @@ type Map[K comparable, V any] struct { // metadata is the h2 metadata array for a group. // find operations first probe the controls bytes // to filter candidates before matching keys -type metadata [groupSize]int8 +type metadata [groupSize]uint8 // group is a group of 16 key-value pairs type group[K comparable, V any] struct { @@ -47,15 +47,15 @@ type group[K comparable, V any] struct { const ( h1Mask uint64 = 0xffff_ffff_ffff_ff80 h2Mask uint64 = 0x0000_0000_0000_007f - empty int8 = -128 // 0b1000_0000 - tombstone int8 = -2 // 0b1111_1110 + empty uint8 = 0b1000_0000 + tombstone uint8 = 0b1111_1110 ) // h1 is a 57 bit hash prefix type h1 uint64 // h2 is a 7 bit hash suffix -type h2 int8 +type h2 uint8 // NewMap constructs a Map. func NewMap[K comparable, V any](sz uint32) (m *Map[K, V]) { @@ -150,7 +150,7 @@ func (m *Map[K, V]) Put(key K, value V) { s := nextMatch(&matches) m.groups[g].keys[s] = key m.groups[g].values[s] = value - m.ctrl[g][s] = int8(lo) + m.ctrl[g][s] = uint8(lo) m.resident++ return } diff --git a/simd/match.s b/simd/match.s index 0e95b87..5aa2e13 100644 --- a/simd/match.s +++ b/simd/match.s @@ -4,11 +4,11 @@ #include "textflag.h" -// func MatchMetadata(metadata *[16]int8, hash int8) uint16 +// func MatchMetadata(metadata *[16]uint8, hash uint8) uint16 // Requires: SSE2, SSSE3 TEXT ·MatchMetadata(SB), NOSPLIT, $0-18 MOVQ metadata+0(FP), AX - MOVBLSX hash+8(FP), CX + MOVBLZX hash+8(FP), CX MOVD CX, X0 PXOR X1, X1 PSHUFB X1, X0 diff --git a/simd/match_amd64.go b/simd/match_amd64.go index 6667d93..ea93a14 100644 --- a/simd/match_amd64.go +++ b/simd/match_amd64.go @@ -6,4 +6,4 @@ package simd // MatchMetadata performs a 16-way probe of |metadata| using SSE instructions // nb: |metadata| must be an aligned pointer -func MatchMetadata(metadata *[16]int8, hash int8) uint16 +func MatchMetadata(metadata *[16]uint8, hash uint8) uint16 diff --git a/simd/src/asm.go b/simd/src/asm.go index 784b184..13ecf45 100644 --- a/simd/src/asm.go +++ b/simd/src/asm.go @@ -23,7 +23,7 @@ import ( func main() { ConstraintExpr("amd64") - TEXT("MatchMetadata", NOSPLIT, "func(metadata *[16]int8, hash int8) uint16") + TEXT("MatchMetadata", NOSPLIT, "func(metadata *[16]uint8, hash uint8) uint16") Doc("MatchMetadata performs a 16-way probe of |metadata| using SSE instructions", "nb: |metadata| must be an aligned pointer") m := Mem{Base: Load(Param("metadata"), GP64())}