14.13 在多核心上并行计算

假设我们有 NCPU 个 CPU 核心:const NCPU = 4 //对应一个四核处理器 然后我们想把计算量分成 NCPU 个部分,每一个部分都和其他部分并行运行。

这可以通过以下代码所示的方式完成(我们且省略具体参数)

  1. func DoAll(){
  2. sem := make(chan int, NCPU) // Buffering optional but sensible
  3. for i := 0; i < NCPU; i++ {
  4. go DoPart(sem)
  5. }
  6. // Drain the channel sem, waiting for NCPU tasks to complete
  7. for i := 0; i < NCPU; i++ {
  8. <-sem // wait for one task to complete
  9. }
  10. // All done.
  11. }
  12. func DoPart(sem chan int) {
  13. // do the part of the computation
  14. sem <-1 // signal that this piece is done
  15. }
  16. func main() {
  17. runtime.GOMAXPROCS(NCPU) // runtime.GOMAXPROCS = NCPU
  18. DoAll()
  19. }
  • DoAll() 函数创建了一个 sem 通道,每个并行计算都将在对其发送完成信号;在一个 for 循环中 NCPU 个协程被启动了,每个协程会承担 1/NCPU 的工作量。每一个 DoPart() 协程都会向 sem 通道发送完成信号。

  • DoAll() 会在 for 循环中等待 NCPU 个协程完成:sem 通道就像一个信号量,这份代码展示了一个经典的信号量模式。(参见 14.2.7

在以上运行模型中,您还需将 GOMAXPROCS 设置为 NCPU(参见 14.1.3)。

链接