LoginSignup
56
39

More than 5 years have passed since last update.

やはり俺のgolangがCPUを一つしか使わないのはまちがっている。

Last updated at Posted at 2015-08-04

複数のCPUを使うマルチスレッドプログラムが簡単に
書けるのがgolangの特徴の一つなのでやってみたが、1CPUしか100%にならない。

1つのCPUしか使われない

calc.go
package main

import (
  "fmt"
  "sync"
  "time"
)

func main() {
  fmt.Println("start")
  var wg sync.WaitGroup
  for _, a := range []string{"1", "2"} {
    wg.Add(1)
    go func(str string) {
      i := 0
      fmt.Println("I'm " + str)
      time.Sleep(1) // 時分割なので2番目が開始するまで待つ
      for {
          i++;
      }
      wg.Done()
    }(a)
  }
  wg.Wait()
  fmt.Println("end")
}
$ go run calc.go &
start
I'm 1
I'm 2

$ mpstat -P ALL 2
平均値:   CPU    %usr  %idle
平均値:     0  100.00   0.00
平均値:     1    0.25  99.50

原因

GOMAXPROCSは初期値1なので、そのままだと1コアを時分割して動作する(並行処理)ので複数のCPUを使う(並列処理)にはGOMAXPROCSにCPU数を入れる。

calc2.go
package main

import (
  "fmt"
  "sync"
  "time"
  "runtime"
)

func main() {
  fmt.Println("start")
  fmt.Printf("NumCPU=%d\n", runtime.NumCPU())
  runtime.GOMAXPROCS(runtime.NumCPU())

  var wg sync.WaitGroup
  for _, a := range []string{"1", "2"} {
    wg.Add(1)
    go func(str string) {
      i := 0
      fmt.Println("I'm " + str)
      time.Sleep(1)
      for {
          i++;
      }
      wg.Done()
    }(a)
  }
  wg.Wait()
  fmt.Println("end")
}
$ go run calc2.go
NumCPU=2
I'm 1
I'm 2
$ mpstat -P ALL 2
平均値:   CPU    %usr   %idle
平均値:     0  100.00   0.00
平均値:     1  100.00   0.00

並行処理と並列処理

calc.goは並行処理、calc2.goは並列処理である。

ドラゴンボールで例えると
並行処理とは孫悟空の多重残像拳で悟空が超高速でそれぞれを切り替えて動いているので一見複数人に見えるが実際は一人。
並列処理とは天津飯の四身の拳で天津飯が実際に4人になっている。

並行処理では1CPUを時分割して動作するので2番目のCPUは使われないため、ずっとidleだったというわけである。

参考

Go - ゴルーチンと並行性パターン - Qiita
http://qiita.com/hayajo/items/4cd75f87e35e60ae11a9#%E4%B8%A6%E8%A1%8C%E6%80%A7%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

Go言語でCPU数に応じて並列処理数を制限する | SOTA
http://deeeet.com/writing/2014/07/30/golang-parallel-by-cpu/

FAQ - golang.jp
http://golang.jp/go_faq#Why_no_multi_CPU

Go - sync.WaitGroupの正しい使い方 - Qiita
http://qiita.com/ruiu/items/dba58f7b03a9a2ffad65

動的言語だけやってた僕が、38日間Go言語を書いて学んだこと - Qiita
http://qiita.com/suin/items/22662f43b6a6e8728798

go - Parallel processing in golang - Stack Overflow
http://stackoverflow.com/questions/25106526/parallel-processing-in-golang

build-web-application-with-golang/02.7.md at master · astaxie/build-web-application-with-golang
https://github.com/astaxie/build-web-application-with-golang/blob/master/ja/02.7.md

並行と並列について-並行コンピューティング技法-を読んで - M-Tea
http://www.m-tea.info/2011/03/concurrent-parallel-01.html

56
39
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
56
39