我尝试了一些同步技术在goroutine之间共享状态,发现不正确的变体(不同步)比使用互斥锁的同一个程序慢。
给出代码:
package main
import (
"sync"
"time"
"fmt"
)
func main() {
var wg sync.WaitGroup
var mu sync.Mutex
hash := make(map[string]string)
hash["test"] = "string"
num := 40000000
wg.Add(num)
start := time.Now()
for i := 0; i < num; i++ {
go func() {
mu.Lock()
_, _ = hash["test"]
mu.Unlock()
wg.Done()
}()
}
wg.Wait()
fmt.Println(time.Since(start))
}
在具有8个HT内核的笔记本电脑上执行9-10秒。 但是,如果只删除同步,则可以使用11到12秒:
package main
import (
"sync"
"time"
"fmt"
)
func main() {
var wg sync.WaitGroup
hash := make(map[string]string)
hash["test"] = "string"
num := 40000000
wg.Add(num)
start := time.Now()
for i := 0; i < num; i++ {
go func() {
_, _ = hash["test"]
wg.Done()
}()
}
wg.Wait()
fmt.Println(time.Since(start))
}
同步版本更快,并且将CPU统一化得更高。问题是为什么?
由于GOMAXPROCS越多,这两个版本之间的差距越大,我的思想是关于goroutine如何安排上下文切换和开销。但是我无法解释在调度程序的后台发生这种情况的真正原因。