如果你的电脑是16核心的话,可以开16个 goroutine 共同计算一列数的的综合,就会发现总的执行时间没有明显缩短。再去观察 CPU 运行状态,你会发现尽管我们有16个 CPU 核心,但在计算过程中其实只有一个 CPU 核心处于繁忙状态,这是会让很多 Go 语言初学者迷惑的问题。
官方的答案是,这是当前版本的 Go 编译器还不能很智能地去发现和利用多核的优势。虽然确实创建了个 goroutine,并且从运行状态看这些 goroutine 也都在并行运行,但实际上所有这些 goroutine 都运行在同一个 CPU 核心上在一个 goroutine 得到时间片执行的时候,其他 goroutine 都会处于等待状态。从这一点可以看出,虽然 goroutine 简化了写并行代码的过程,但实际上整体运行效率并不真正高于单线程程序。
在 Go 语言升级到默认支持多 CPU 的某个版本之前,可以先通过设置环境变量 GOMAXPROCS
的值来控制使用多少个 CPU 核心。具体操作方法是通过直接设置环境变量 GOMAXPROCS 的值,或者在代码中启动 goroutine 之前先调用以下这个语句以设置使用16个CPU核心:
runtime.GOMAXPROCS(16)
到底应该设置多少个 CPU 核心呢,其实 runtime 包中还提供了另外一个函数 NumCPU() 来获取核心数。可以看到,Go 语言其实已经感知到所有的环境信息,下一版本中完全可以利用这些信息将 goroutine 调度到所有 CPU 核心上,从而最大化地利用服务器的多核计算能力。抛弃 GOMAXPROCS 只是个时间问题。
文章评论