为什么go语句并行执行?

Odo*_*ois 8 parallel-processing multicore go

我正在我的VirtualBoxed Ubuntu 11.4上测试这个代码

package main

import ("fmt";"time";"big")
var c chan *big.Int

func sum( start,stop,step int64) {
    bigStop := big.NewInt(stop)
    bigStep := big.NewInt(step)
    bigSum  := big.NewInt(0)
    for i := big.NewInt(start);i.Cmp(bigStop)<0 ;i.Add(i,bigStep){
        bigSum.Add(bigSum,i)
    }
    c<-bigSum           
}

func main() {
    s := big.NewInt( 0 )
    n := time.Nanoseconds()

    step := int64(4)
    c = make( chan *big.Int , int(step))
    stop := int64(100000000)
    for j:=int64(0);j<step;j++{
        go sum(j,stop,step)     
    }
    for j:=int64(0);j<step;j++{
        s.Add(s,<-c)
    }
    n = time.Nanoseconds() - n
    fmt.Println(s,float64(n)/1000000000.)
}
Run Code Online (Sandbox Code Playgroud)

Ubuntu可以访问我的所有4个核心.我通过同时运行几个可执行文件和系统监视器来检查这个.但是,当我尝试运行此代码时,它只使用一个核心,并没有获得并行处理的任何利润.

我做错了什么?

Nic*_*ght 24

您可能需要查看Go常见问题解答并发部分,特别是这两个问题,并确定哪些(如果不是两者)适用于您的案例:

为什么我的multi-goroutine程序不使用多个CPU?

您必须设置GOMAXPROCS shell环境变量或使用 运行时包的类似命名的函数,以允许运行时支持使用多个OS线程.

执行并行计算的程序应该受益于GOMAXPROCS的增加.但是,请注意并发不是并行性.

为什么使用GOMAXPROCS> 1有时会使我的程序变慢?

这取决于您的计划的性质.在使用多个OS线程时,包含花费大量时间在通道上进行通信的多个goroutine的程序将遇到性能下降.这是因为在线程之间发送数据时涉及显着的上下文切换惩罚.

Go的goroutine调度程序并不像它需要的那样好.将来,它应该识别这种情况并优化其对OS线程的使用.目前,应该基于每个应用程序设置GOMAXPROCS.

有关此主题的更多详细信息,请参阅题为" 并发不是并行"的演讲.