Я попробовал некоторые методы синхронизации, чтобы разделить состояние между программами и выяснить, что неправильный вариант (без синхронизации) работает медленнее, чем та же программа с мьютексом.
Учитывая код:
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))
}
Синхронизированная версия работает быстрее и значительно повышает производительность процессора.Вопрос в том, почему?
Я думаю о том, как запланированы и загружены подпрограммы для переключения контекста из-за того, что чем больше GOMAXPROCS, тем больше разрыв между этими двумя версиями.Но я не могу объяснить истинную причину того, что происходит под капотом планировщика.