Improve the exponential backoff algorithm in spin-lock

This commit is contained in:
Andy Pan 2021-06-22 18:06:51 +08:00
parent 1ce7c89177
commit 4b16a81116
2 changed files with 17 additions and 1 deletions

View File

@ -12,14 +12,19 @@ import (
type spinLock uint32 type spinLock uint32
const maxBackoff = 64
func (sl *spinLock) Lock() { func (sl *spinLock) Lock() {
backoff := 1 backoff := 1
for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) { for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
// Leverage the exponential backoff algorithm, see https://en.wikipedia.org/wiki/Exponential_backoff.
for i := 0; i < backoff; i++ { for i := 0; i < backoff; i++ {
runtime.Gosched() runtime.Gosched()
} }
if backoff < maxBackoff {
backoff <<= 1 backoff <<= 1
} }
}
} }
func (sl *spinLock) Unlock() { func (sl *spinLock) Unlock() {

View File

@ -11,6 +11,17 @@ import (
"testing" "testing"
) )
/*
Benchmark result for three types of locks:
goos: darwin
goarch: amd64
pkg: github.com/panjf2000/ants/v2/internal
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkMutex-12 20549502 71.84 ns/op 0 B/op 0 allocs/op
BenchmarkSpinLock-12 58629697 20.02 ns/op 0 B/op 0 allocs/op
BenchmarkBackOffSpinLock-12 72523454 15.74 ns/op 0 B/op 0 allocs/op
*/
type originSpinLock uint32 type originSpinLock uint32
func (sl *originSpinLock) Lock() { func (sl *originSpinLock) Lock() {