Go
golang

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

More than 3 years have passed since last update.

複数の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