

GO言語を使って、効率良い計算のため並列化を目指しています。  
その時に、少し疑問に思いましたので、質問させていただいています。

まず、toy scriptを示して、その後に質問いたします。

[code]

    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);
    }
    
[/code]

ここで行っていることは、sleepをfunction化しまして、それを１０回繰り返しています程度のものです。上記のscriptでは、２つの方法を試しています。

上記のscriptの計算結果は、  
single run time: 10.001401547s  
parallel run time: 1.027465324s  
となります。

(1) "single run"では「１秒休み」を１０回繰り返しているため１０秒かかり  
(２) "parallel run"では、「１秒休み」を１０回同時に行っているため１秒で計算が終わる  
と理解しています。

実際には、functionで行っていることが少し複雑です。そのため（２）のケースで計算を行いますと、各processでの計算がカチアイ、その結果、計算時間が(1)のケースより時間がかかってしまっています。

上記では、並列計算したい数が１０ですが、実際には300~1000ほどを予定しています。

また、runtime.GOMAXPROCS(1)を「１」に設定していますが、  
この数字を変更してもやはり同じ問題が起きてしまいます。  
（使っているPCのCPU数が８です）

そこで、質問ですが、  
GOMAXPROCSで指定した数だけ一時的に並列化をすることができるのでしょうか？

具体的には、  
runtime.GOMAXPROCS(5)の時、「１秒休み」を５回同時に行い、それが終わったら、次の５回を行うことで、（一回目の１秒と２回目の秒で）計算時間を２秒にすることは可能でしょうか？

もし可能であれば、scriptのどの部分を変更することでそれが可能になるのかを示唆していただけると、大変ありがたいです。

ご教授、よろしくお願いします。


CC BY-SA 3.0
2017-08-04T11:26:50.047
36946
2017-08-04T11:26:50.047
11048
question
go
GO言語での並列計算の仕組みについて