From 6d4770ecd88cdab5992bb5a8ff809b6944f83096 Mon Sep 17 00:00:00 2001 From: Respawnz <47511522+Respawnz@users.noreply.github.com> Date: Thu, 11 Jul 2019 12:20:09 +0800 Subject: [PATCH] =?UTF-8?q?14.13=20Parallelizing=20a=20computation=20over?= =?UTF-8?q?=20a=20number=20of=20cores=20=E5=9C=A8=E5=A4=9A=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E4=B8=8A=E5=B9=B6=E8=A1=8C=E8=AE=A1=E7=AE=97=20(#629)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create 14.13.md * Update 14.13.md * Update 14.13.md * Update 14.13.md --- eBook/14.13.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 eBook/14.13.md diff --git a/eBook/14.13.md b/eBook/14.13.md new file mode 100644 index 0000000..cb4bbac --- /dev/null +++ b/eBook/14.13.md @@ -0,0 +1,42 @@ +# 14.13 在多核心上并行计算 + +假设我们有`NCPU`个CPU核心:`const NCPU = 4 //对应一个四核处理器` 然后我们想把计算量分成`NCPU`个部分,每一个部分都和其他部分并行运行。 + +这可以通过以下代码所示的方式完成(我们且省略具体参数) + +```go +func DoAll(){ + sem := make(chan int, NCPU) // Buffering optional but sensible + for i := 0; i < NCPU; i++ { + go DoPart(sem) + } + // Drain the channel sem, waiting for NCPU tasks to complete + for i := 0; i < NCPU; i++ { + <-sem // wait for one task to complete + } + // All done. +} + +func DoPart(sem chan int) { + // do the part of the computation + sem <-1 // signal that this piece is done +} + +func main() { + runtime.GOMAXPROCS = NCPU + DoAll() +} + +``` +- `DoAll()`函数创建了一个`sem`通道,每个并行计算都将在对其发送完成信号;在一个 for 循环中`NCPU`个协程被启动了,每个协程会承担`1/NCPU`的工作量。每一个`DoPart()`协程都会向`sem`通道发送完成信号。 + +- `DoAll()`会在 for 循环中等待`NCPU`个协程完成:`sem`通道就像一个信号量,这份代码展示了一个经典的信号量模式。(参见 [14.2.7](14.2.md#1427-%E4%BF%A1%E5%8F%B7%E9%87%8F%E6%A8%A1%E5%BC%8F)) + +在以上运行模型中,您还需将`GOMAXPROCS`设置为`NCPU`(参见 [14.1.3](14.1.md#1413-%E4%BD%BF%E7%94%A8-gomaxprocs))。 + + +## 链接 + +- [目录](directory.md) +- 上一节:[协程链](14.12.md) +- 下一节:[并行化大量数据的计算](14.14.md)