我正在我的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个内核。我通过同时运行几个可执行文件和系统监视器来检查这一点。但是,当我尝试运行此代码时,它仅使用一个内核,并且没有从并行处理中获得任何收益。
我做错了什么?
您可能需要查看Go FAQ的Concurrency部分,特别是以下两个问题,并确定哪个(如果不是两个)适用于您的情况:
为什么我的多goroutine程序不使用多个CPU? 您必须设置GOMAXPROCS shell环境变量或使用 运行时包的类似名称的函数,以允许运行时支持利用多个OS线程。 执行并行计算的程序应受益于GOMAXPROCS的增加。但是,请注意并发不是并行性。 为什么使用GOMAXPROCS > 1有时会使我的程序变慢? 这取决于程序的性质。当使用多个OS线程时,包含多个goroutine且花费大量时间在通道上进行通信的程序会遇到性能下降的情况。这是因为在线程之间发送数据涉及大量上下文切换损失。 Go的goroutine调度程序不尽如人意。将来,它应该认识到这种情况并优化对OS线程的使用。目前,应基于每个应用程序设置GOMAXPROCS。 有关此主题的更多详细信息,请参见标题为“ 并发不是并行性”的主题。
为什么我的多goroutine程序不使用多个CPU?
您必须设置GOMAXPROCS shell环境变量或使用 运行时包的类似名称的函数,以允许运行时支持利用多个OS线程。
执行并行计算的程序应受益于GOMAXPROCS的增加。但是,请注意并发不是并行性。
为什么使用GOMAXPROCS > 1有时会使我的程序变慢?
这取决于程序的性质。当使用多个OS线程时,包含多个goroutine且花费大量时间在通道上进行通信的程序会遇到性能下降的情况。这是因为在线程之间发送数据涉及大量上下文切换损失。
Go的goroutine调度程序不尽如人意。将来,它应该认识到这种情况并优化对OS线程的使用。目前,应基于每个应用程序设置GOMAXPROCS。
有关此主题的更多详细信息,请参见标题为“ 并发不是并行性”的主题。