compare atomic and mutex performance in case of contention. (#1788)
This commit is contained in:
@ -277,55 +277,82 @@ func BenchmarkAtomicTimePointerStore(b *testing.B) {
|
|||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkValueStoreWithContention(b *testing.B) {
|
func BenchmarkStoreContentionWithAtomic(b *testing.B) {
|
||||||
t := 123
|
t := 123
|
||||||
for _, n := range []int{10, 100, 1000, 10000, 100000} {
|
var c unsafe.Pointer
|
||||||
b.Run(fmt.Sprintf("Atomic/%v", n), func(b *testing.B) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
var wg sync.WaitGroup
|
for pb.Next() {
|
||||||
var c atomic.Value
|
atomic.StorePointer(&c, unsafe.Pointer(&t))
|
||||||
for i := 0; i < n; i++ {
|
}
|
||||||
wg.Add(1)
|
})
|
||||||
go func() {
|
}
|
||||||
for j := 0; j < b.N; j++ {
|
|
||||||
c.Store(t)
|
func BenchmarkStoreContentionWithMutex(b *testing.B) {
|
||||||
|
t := 123
|
||||||
|
var mu sync.Mutex
|
||||||
|
var c int
|
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
mu.Lock()
|
||||||
|
c = t
|
||||||
|
mu.Unlock()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
_ = c
|
||||||
|
}
|
||||||
|
|
||||||
|
type dummyStruct struct {
|
||||||
|
a int64
|
||||||
|
b time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkStructStoreContention(b *testing.B) {
|
||||||
|
d := dummyStruct{}
|
||||||
|
dp := unsafe.Pointer(&d)
|
||||||
|
t := time.Now()
|
||||||
|
for _, j := range []int{100000000, 10000, 0} {
|
||||||
|
for _, i := range []int{100000, 10} {
|
||||||
|
b.Run(fmt.Sprintf("CAS/%v/%v", j, i), func(b *testing.B) {
|
||||||
|
b.SetParallelism(i)
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
n := &dummyStruct{
|
||||||
|
b: t,
|
||||||
}
|
}
|
||||||
wg.Done()
|
for pb.Next() {
|
||||||
}()
|
for y := 0; y < j; y++ {
|
||||||
}
|
}
|
||||||
wg.Wait()
|
for {
|
||||||
})
|
v := (*dummyStruct)(atomic.LoadPointer(&dp))
|
||||||
b.Run(fmt.Sprintf("AtomicStorePointer/%v", n), func(b *testing.B) {
|
n.a = v.a + 1
|
||||||
var wg sync.WaitGroup
|
if atomic.CompareAndSwapPointer(&dp, unsafe.Pointer(v), unsafe.Pointer(n)) {
|
||||||
var up unsafe.Pointer
|
n = v
|
||||||
for i := 0; i < n; i++ {
|
break
|
||||||
wg.Add(1)
|
}
|
||||||
go func() {
|
}
|
||||||
for j := 0; j < b.N; j++ {
|
|
||||||
atomic.StorePointer(&up, unsafe.Pointer(&t))
|
|
||||||
}
|
}
|
||||||
wg.Done()
|
})
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
wg.Wait()
|
}
|
||||||
})
|
|
||||||
b.Run(fmt.Sprintf("Mutex/%v", n), func(b *testing.B) {
|
var mu sync.Mutex
|
||||||
var wg sync.WaitGroup
|
for _, j := range []int{100000000, 10000, 0} {
|
||||||
var c int
|
for _, i := range []int{100000, 10} {
|
||||||
mu := sync.Mutex{}
|
b.Run(fmt.Sprintf("Mutex/%v/%v", j, i), func(b *testing.B) {
|
||||||
for i := 0; i < n; i++ {
|
b.SetParallelism(i)
|
||||||
wg.Add(1)
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
go func() {
|
for pb.Next() {
|
||||||
for j := 0; j < b.N; j++ {
|
for y := 0; y < j; y++ {
|
||||||
|
}
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
c = t
|
d.a++
|
||||||
|
d.b = t
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
}
|
}
|
||||||
wg.Done()
|
})
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
_ = c
|
|
||||||
wg.Wait()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user