【问题标题】:Is there a simple `parallel for` in golang like OpenMP?在像 OpenMP 这样的 golang 中是否有一个简单的“parallel for”?
【发布时间】:2016-08-25 06:09:44
【问题描述】:

我正在尝试通过并行处理优化谜题,以获得更好的性能。

理想情况下,在带有 OpenMP 的 C99 中,我应该能够在 #pragma omp parallel for 之前的 for 循环的帮助下做到这一点,然后应该由系统来分配负载CPU。

然而,https://golang.org/doc/effective_go.html#parallel 的 Go 官方文档似乎建议,对于并行处理,我必须 (0) 从运行时环境中手动获取内核数,(1),遍历所述内核,( 2),有效地为每个内核编写一个不同的 for 循环,(3),再次循环内核以确保所有内容都得到处理。

我错过了什么吗?对于最简单的情况,带有古老 C 的 OpenMP 是否优于被吹捧为 C 最佳替代品的全新 Go?对于更复杂的示例,您如何在 CPU 之间拆分 range

【问题讨论】:

  • @Amd,肤浅的编辑(以及引入拼写错误)违反 ToS

标签: c go parallel-processing openmp


【解决方案1】:

Effective Go 已经过时了,Go 自动将 GOMAXPROCS 设置为处理器的数量(您仍然可以手动设置它以强制使用您想要的数量)。

下面是一个非常简单的切片并行处理示例:

data := make([]float64, SZ)
var wg sync.WaitGroup
for i := range data {
    wg.Add(1)
    go func(v *float64) {
        // note that using rand is a bad example because global rand uses a mutex
        *v = rand.Float64()
        wg.Done()
    }(&data[i])
}
wg.Wait()

playground

【讨论】:

  • 看起来不错,但是,我试过了,它似乎并没有提供任何性能提升,我的 for 循环大约 2k 元素实际上运行了 39 秒,仍然只使用 12.5% 的 CPU (根据顶部),而非常规版本在 29 秒内完成。
  • 还要注意,上面的示例代码正在创建 goroutines。请理解 goroutine 不像原生操作系统线程,它们是它们之上的抽象。运行时跨 cpu 内核对 goroutine 进行时间切片,避免您显式地执行此操作。在许多情况下,与内核数量相比,拥有过多的 goroutine 是一件好事(确实有理论工作支持这一点 [Valiant 和其他人])。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 2019-06-26
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
相关资源
最近更新 更多