Skip to content

Commit

Permalink
malloc: optimize sharded counter to avoid false sharing
Browse files Browse the repository at this point in the history
  • Loading branch information
reusee committed Jun 26, 2024
1 parent 56a10eb commit d502f84
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions pkg/common/malloc/sharded_counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

package malloc

import "golang.org/x/sys/cpu"

type AtomicInteger[T any] interface {
Add(T) T
Load() T
Expand All @@ -27,28 +29,33 @@ type ShardedCounter[T CounterInteger, A any, P interface {
*A
AtomicInteger[T]
}] struct {
shards []A
shards []shardedCounterShard[A]
}

type shardedCounterShard[T any] struct {
value T
_ cpu.CacheLinePad
}

func NewShardedCounter[T CounterInteger, A any, P interface {
*A
AtomicInteger[T]
}](shards int) *ShardedCounter[T, A, P] {
return &ShardedCounter[T, A, P]{
shards: make([]A, shards),
shards: make([]shardedCounterShard[A], shards),
}
}

func (s *ShardedCounter[T, A, P]) Add(v T) {
pid := runtime_procPin()
runtime_procUnpin()
shard := pid % len(s.shards)
P(&s.shards[shard]).Add(v)
P(&s.shards[shard].value).Add(v)
}

func (s *ShardedCounter[T, A, P]) Load() (ret T) {
for i := 0; i < len(s.shards); i++ {
ret += P(&s.shards[i]).Load()
ret += P(&s.shards[i].value).Load()
}
return ret
}

0 comments on commit d502f84

Please sign in to comment.