mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/uint64set: improve Set.Has() performance scalability on multi-CPU system
Do not update bucket32.hint on Set.Has() call, since it leads to memory ping-pong between CPU cores multi-CPU system
This commit is contained in:
parent
2601cc0fb0
commit
b75c2ce659
1 changed files with 2 additions and 24 deletions
|
@ -186,19 +186,6 @@ func (s *Set) Has(x uint64) bool {
|
||||||
hi32 := uint32(x >> 32)
|
hi32 := uint32(x >> 32)
|
||||||
lo32 := uint32(x)
|
lo32 := uint32(x)
|
||||||
bs := s.buckets
|
bs := s.buckets
|
||||||
if len(bs) > 0 && bs[0].hi == hi32 {
|
|
||||||
// Manually inline bucket32.has for performance reasons.
|
|
||||||
hi16 := uint16(lo32 >> 16)
|
|
||||||
lo16 := uint16(lo32)
|
|
||||||
b32 := &bs[0]
|
|
||||||
his := b32.b16his
|
|
||||||
if n := b32.getHint(); n < uint32(len(his)) && his[n] == hi16 {
|
|
||||||
// Fast path - check the previously used bucket.
|
|
||||||
bs := b32.buckets
|
|
||||||
return n < uint32(len(bs)) && bs[n].has(lo16)
|
|
||||||
}
|
|
||||||
return b32.hasSlow(hi16, lo16)
|
|
||||||
}
|
|
||||||
for i := range bs {
|
for i := range bs {
|
||||||
b32 := &bs[i]
|
b32 := &bs[i]
|
||||||
if b32.hi == hi32 {
|
if b32.hi == hi32 {
|
||||||
|
@ -671,22 +658,13 @@ func (b *bucket32) addBucketAtPos(hi uint16, pos int) *bucket16 {
|
||||||
func (b *bucket32) has(x uint32) bool {
|
func (b *bucket32) has(x uint32) bool {
|
||||||
hi := uint16(x >> 16)
|
hi := uint16(x >> 16)
|
||||||
lo := uint16(x)
|
lo := uint16(x)
|
||||||
his := b.b16his
|
|
||||||
if n := b.getHint(); n < uint32(len(his)) && his[n] == hi {
|
|
||||||
// Fast path - check the previously used bucket.
|
|
||||||
bs := b.buckets
|
|
||||||
return n < uint32(len(bs)) && bs[n].has(lo)
|
|
||||||
}
|
|
||||||
return b.hasSlow(hi, lo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bucket32) hasSlow(hi, lo uint16) bool {
|
|
||||||
his := b.b16his
|
his := b.b16his
|
||||||
n := binarySearch16(his, hi)
|
n := binarySearch16(his, hi)
|
||||||
if n < 0 || n >= len(his) || his[n] != hi {
|
if n < 0 || n >= len(his) || his[n] != hi {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
b.setHint(n)
|
// Do not call b.setHint(n) here, since this may trash performance
|
||||||
|
// when many concurrent goroutines call b.has() method from many CPU cores.
|
||||||
bs := b.buckets
|
bs := b.buckets
|
||||||
return n < len(bs) && bs[n].has(lo)
|
return n < len(bs) && bs[n].has(lo)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue