GO言語での並列計算の仕組みについて
GO言語を使って、効率良い計算のため並列化を目指しています。
その時に、少し疑問に思いましたので、質問させていただいています。
まず、toy scriptを示して、その後に質問いたします。
package main
import (
"fmt"
"time"
"sync"
"runtime"
)
var wg sync.WaitGroup
func sleep1(i int) {
fmt.Println(i)
time.Sleep(1 * time.Second)
}
func sleep2(i int) {
fmt.Println(i)
time.Sleep(1 * time.Second)
defer wg.Done()
}
func main() {
runtime.GOMAXPROCS(1)
t1 := time.Now();
//This is for single run
for i:=0; i<10; i++ {
sleep1(i);
}
diff1 := time.Now().Sub(t1);
t2 := time.Now();
//Running in parallel
for i:=0; i<10; i++ {
wg.Add(1)
go sleep2(i);
}
wg.Wait()
diff2 := time.Now().Sub(t2);
fmt.Println("single run time:", diff1);
fmt.Println("parallel run time:", diff2);
}
ここで行っていることは、sleepをfunction化しまして、それを10回繰り返しています程度のものです。上記のscriptでは、2つの方法を試しています。
上記のscriptの計算結果は、
single run time: 10.001401547s
parallel run time: 1.027465324s
となります。
(1) "single run"では「1秒休み」を10回繰り返しているため10秒かかり
(2) "parallel run"では、「1秒休み」を10回同時に行っているため1秒で計算が終わる
と理解しています。
実際には、functionで行っていることが少し複雑です。そのため(2)のケースで計算を行いますと、各processでの計算がカチアイ、その結果、計算時間が(1)のケースより時間がかかってしまっています。
上記では、並列計算したい数が10ですが、実際には300~1000ほどを予定しています。
また、runtime.GOMAXPROCS(1)を「1」に設定していますが、
この数字を変更してもやはり同じ問題が起きてしまいます。
(使っているPCのCPU数が8です)
そこで、質問ですが、
GOMAXPROCSで指定した数だけ一時的に並列化をすることができるのでしょうか?
具体的には、
runtime.GOMAXPROCS(5)の時、「1秒休み」を5回同時に行い、それが終わったら、次の5回を行うことで、(一回目の1秒と2回目の秒で)計算時間を2秒にすることは可能でしょうか?
もし可能であれば、scriptのどの部分を変更することでそれが可能になるのかを示唆していただけると、大変ありがたいです。
ご教授、よろしくお願いします。