小编典典

为什么Go语句不并行执行?

go

我正在我的VirtualBoxed Ubuntu 11.4上测试此Go代码

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.)
}

Ubuntu可以访问我所有的4个内核。我通过同时运行几个可执行文件和系统监视器来检查这一点。但是,当我尝试运行此代码时,它仅使用一个内核,并且没有从并行处理中获得任何收益。

我做错了什么?


阅读 374

收藏
2020-07-02

共1个答案

小编典典

您可能需要查看Go
FAQ
Concurrency部分,特别是以下两个问题,并确定哪个(如果不是两个)适用于您的情况:

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

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

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

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

这取决于程序的性质。当使用多个OS线程时,包含多个goroutine且花费大量时间在通道上进行通信的程序会遇到性能下降的情况。这是因为在线程之间发送数据涉及大量上下文切换损失。

Go的goroutine调度程序不尽如人意。将来,它应该认识到这种情况并优化对OS线程的使用。目前,应基于每个应用程序设置GOMAXPROCS。

有关此主题的更多详细信息,请参见标题为“
并发不是并行性”的主题

2020-07-02