Ric*_*777 37 multithreading go
Goroutines是轻量级进程,由Go运行时自动切片到一个或多个操作系统线程上.(这是Go的一个非常酷的功能!)
假设我有一个像Web服务器一样的并发应用程序.在我的假设计划中同时发生了大量的事情,没有太多的非并发(Amdahl定律)比率.
似乎使用的默认操作系统线程数目是1.这是否意味着只使用一个CPU核心?
如果我开始我的程序
runtime.GOMAXPROCS(runtime.NumCPU())
Run Code Online (Sandbox Code Playgroud)
是否可以合理有效地使用我PC上的所有内核?
使用更多的 OS线程是否有任何"并行松弛"的好处,例如通过一些启发式方法
runtime.GOMAXPROCS(runtime.NumCPU() * 2)
Run Code Online (Sandbox Code Playgroud)
?
Lin*_*ope 59
来自Go FAQ:
为什么我的multi-goroutine程序不使用多个CPU?
您必须设置GOMAXPROCS shell环境变量或使用运行时包的类似命名的函数,以允许运行时支持使用多个OS线程.
执行并行计算的程序应该受益于GOMAXPROCS的增加.但是,请注意并发不是并行性.
(更新2015年8月28日:Go 1.5设置为使GOMAXPROCS的默认值与您机器上的CPU数量相同,因此这不应该成为问题)
和
为什么使用GOMAXPROCS> 1有时会使我的程序变慢?
这取决于您的计划的性质.通过添加更多goroutine无法加速本质上顺序的问题.当问题本质上是并行时,并发只会变成并行性.
实际上,在使用多个OS线程时,花费更多时间在通道上进行通信而不是进行计算的程序将会出现性能下降.这是因为在线程之间发送数据涉及切换上下文,这具有显着的成本.例如,Go规范中的主筛网示例没有显着的并行性,尽管它启动了许多goroutines; 增加GOMAXPROCS更有可能减慢速度,而不是加快速度.
Go的goroutine调度程序并不像它需要的那样好.将来,它应该识别这种情况并优化其对OS线程的使用.目前,应该基于每个应用程序设置GOMAXPROCS.
简而言之:让Go使用"有效利用所有核心"非常困难.简单地产生十亿个goroutines并增加GOMAXPROCS就像降低你的性能一样,因为它会一直在切换线程上下文.如果你有一个可并行化的大型程序,那么将GOMAXPROCS增加到并行组件的数量就可以了.如果你在一个很大程度上非并行的程序中嵌入了并行问题,它可能会加速,或者你可能必须创造性地使用诸如runtime.LockOSThread()之类的函数来确保运行时正确地分配所有内容(一般来说,只是愚蠢地传播目前非阻塞Goroutines偶然和均匀地在所有活动线程中).
此外,GOMAXPROCS是要使用的CPU核心数,如果它大于NumCPU,我相当肯定它只是钳制到NumCPU.GOMAXPROCS并不严格等于线程数.我并不完全确定运行时决定何时生成新线程,但是一个实例是当使用runtime.LockOSThread()的阻塞goroutines的数量大于或等于GOMAXPROC时 - 它将产生比核心更多的线程所以它可以保持程序的其余部分运行良好.
基本上,增加GOMAXPROCS并使用 CPU的所有内核非常简单.在Go的开发中,这是另一回事,实际上是让它巧妙而高效地使用 CPU的所有核心,需要大量的程序设计和指导才能做到正确.
这个问题无法回答,太宽泛了。
考虑你的问题、你的算法和你的工作量,并衡量什么最适合这个组合。
没有人能回答这样的问题:“是否有任何启发可以证明在午餐中添加两倍的盐会使它的味道更好?” 因为这取决于午餐(西红柿比草莓更能从盐中受益),您的口味以及已有的盐量。尝试一下。
更多:已达到狂热状态,但通过从外部runtime.GOMAXPROCS(runtime.NumCPU())
设置 GOMAXPROCS 环境变量来控制线程数量可能是更好的选择。
归档时间: |
|
查看次数: |
29850 次 |
最近记录: |