4

Go でいくつかの実験を行っていたところ、非常に奇妙なことがわかりました。コンピューターで次のコードを実行すると、約 0.5 秒で実行されます。

package main

import (
  "fmt"
  "runtime"
  "time"
)
func waitAround(die chan bool) {
  <- die
}
func main() {
  var startMemory runtime.MemStats
  runtime.ReadMemStats(&startMemory)

  start := time.Now()
  cpus := runtime.NumCPU()
  runtime.GOMAXPROCS(cpus)
  die := make(chan bool)
  count := 100000
  for i := 0; i < count; i++ {
    go waitAround(die)
  }
  elapsed := time.Since(start)

  var endMemory runtime.MemStats
  runtime.ReadMemStats(&endMemory)

  fmt.Printf("Started %d goroutines\n%d CPUs\n%f seconds\n",
    count, cpus, elapsed.Seconds())
  fmt.Printf("Memory before %d\nmemory after %d\n", startMemory.Alloc,
    endMemory.Alloc)
  fmt.Printf("%d goroutines running\n", runtime.NumGoroutine())
  fmt.Printf("%d bytes per goroutine\n", (endMemory.Alloc - startMemory.Alloc)/uint64(runtime.NumGoroutine()))

  close(die)
}

ただし、それを使用しruntime.GOMAXPROCS(1)て実行すると、はるかに高速に実行されます (~0.15 秒)。多くのゴルーチンを実行すると、より多くのコアを使用すると遅くなる理由を誰か説明できますか? ゴルーチンを複数のコアに多重化すると、大きなオーバーヘッドはありますか? ゴルーチンは何もしていないことに気づきました。ルーチンが実際に何かを行うのを待つ必要があるとしたら、おそらく別の話になるでしょう。

4

2 に答える 2