Goroutines 不使用 Max CPU 和 Cores

Goroutines not Using Max CPU and Cores

我正在实现我的第一个 Golang 应用程序,我在使用 GoRoutines 时遇到了一些关于使用 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()

我在执行应用程序时分享 htop 的两个屏幕截图

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

如何正确使用 Max CPU 和 Cores?

提前致谢。

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

Here are some of the advantages of Goroutines over threads:

  • You can run more goroutines on a typical system than you can threads.
  • Goroutines have growable segmented stacks.
  • Goroutines have a faster startup time than threads.
  • Goroutines come with built-in primitives to communicate safely between themselves (channels).
  • Goroutines allow you to avoid having to resort to mutex locking when sharing data structures.
  • Goroutines are multiplexed onto a small number of OS threads, rather than a 1:1 mapping.
  • You can write massively concurrent servers without having to resort to evented programming.

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

在四处阅读、获得一些提示并尝试一些东西之后,结果发现代码编写得很好,并没有因此导致真正的问题。

本质上,Go 扩展性很好,生成的 tasks 越多,使用的 CPU 资源就越多。

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

希望对大家有所帮助。