compare atomic and mutex performance in case of contention. (#1788)

This commit is contained in:
lyuxuan
2018-01-22 18:48:20 -08:00
committed by GitHub
parent b71aced4a2
commit 4f7a2c71d3

View File

@ -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()
})
} }
} }