【问题标题】:Goroutines not Using Max CPU and CoresGoroutines 不使用 Max CPU 和 Cores
【发布时间】:2017-03-11 13:52:03
【问题描述】:

我正在实现我的第一个Golang 应用程序,但在使用MAX CPU & Cores 时遇到了一些问题,我真的不知道为什么。

使用htop 等工具时,CPU 不会以最大功率使用,只有1..4 threads 处于活动状态。此外,所有cores 都处于活动状态,但它们的利用率都在25%-40% 附近。

我用过:

func MaxParallelism() int {
    maxProcs := runtime.GOMAXPROCS(0)
    numCPU := runtime.NumCPU()
    if maxProcs < numCPU {
        return maxProcs
    }
    return numCPU
}

为了得到goroutines的个数被实例化。

这是我设置应用程序的方式:

//Common Channel for the goroutines
tasks := make(chan *exec.Cmd, 64)

    //Spawning Max Cores Number goroutines (8)
    var wg sync.WaitGroup
    cores := MaxParallelism()
    for i := 0; i < cores; i++ {
        wg.Add(1)
        go func(num int, w *sync.WaitGroup) {
            defer w.Done()
            var (
                out []byte
                err error
            )
            for cmd := range tasks {
                out, err = cmd.Output()
                if err != nil {
                    fmt.Printf("Can't get stdout:", err)
                }
                . . .
            }
        }(i, &wg)
    }

    //Generate Tasks
    for i := 0; i < 100000; i++ {
      tasks <- exec.Command(cmd1, args...)
      tasks <- exec.Command(cmd2, args...)
    }

close(tasks)
// wait for the workers to finish
wg.Wait()

我在执行应用程序时分享了@98​​7654336@ 的两张截图

我不知道它是否有帮助,但我正在通过 Intellij Idea 启动它。

如何正确使用 Max CPU 和 Cores?

提前致谢。

【问题讨论】:

  • 是什么让您认为它没有使用足够的 CPU 内核?你期望什么行为,你观察到什么行为?
  • 我在执行应用程序时共享htop 的屏幕,以便您了解它。基本上,一次只有1 thread active,所有内核的使用率都在 25% 左右。
  • 你说你正在生成 4 个 goroutine。你怎么知道你得到了 4 个?
  • 这是一个错误,我使用 for 生成了 8 个并给它 Max Cores。
  • 你的 goroutine 只是在生成其他进程。您的 Go 进程没有进行任何实际工作,那么为什么它会占用任何 CPU 时间?

标签: go concurrency goroutine


【解决方案1】:

Goroutines 和线程是不一样的。因此,您不应该期望任何 CPU 亲和力。在此处查看更多详情http://tleyden.github.io/blog/2014/10/30/goroutines-vs-threads/

以下是 Goroutine 相对于线程的一些优势:

  • 您可以在典型系统上运行比线程更多的 goroutine。
  • Goroutines 有可增长的分段堆栈。
  • Goroutines 的启动时间比线程快。
  • Goroutines 带有内置的原语,可以在它们之间(通道)安全地通信。
  • Goroutine 允许您在共享数据结构时避免使用互斥锁。
  • Goroutine 被多路复用到少数操作系统线程上,而不是 1:1 映射。
  • 您可以编写大量并发服务器,而无需诉诸事件编程。

编辑: 在 cmets 中回答您的问题。没有确定的答案。正如其他人提到的,这取决于您的代码的作用。例如,如果您执行 I/O,那么您可能永远不会使用 100% 的 CPU,这很慢。因此,无论您启动多少例程,I/O 都很慢。相反,如果你的 goroutine 有一个非常紧凑的循环只做一些计算,那么 8 个 goroutine 很可能会完全消耗你的 8 个 CPU。

【讨论】:

  • 感谢您的回答。正如我所说,我对 Go 来说总体来说还是很陌生,而且我不知道很多事情,因为我从几天就开始使用它。所以,基本上,我应该用 4 个内核和一个坚固的 I7 实例化许多 goroutine 吗?我只想最大限度地利用我的资源。
【解决方案2】:

阅读后,得到一些提示并尝试了一些东西,结果发现代码写得很好,并没有引起真正的问题。

基本上,Go 的可扩展性非常好,生成的tasks 越多,使用的CPU 资源就越多。

例如,在for 上设置更高的范围,例如1.000.000,让Go 使用cores 提供的所有~55% 的可能性。

我希望它会对某人有所帮助。

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2012-08-14
    • 2021-02-20
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2019-06-16
    相关资源
    最近更新 更多