首页 > 解决方案 > 为什么 Go 使用更多的 CPU 却没有减少计算时间?

问题描述

我编写了一个简单的 Go 程序来在许多 goroutine 中添加数字。
当我增加 goroutine 的数量时,程序会使用更多的 CPU,我希望计算持续时间更短。对于 1、2 或 4 个 goroutine 来说确实如此,但是当我尝试 8 个 goroutine 时,持续时间与 4 相同(我在 i5-8265U,一个 8 CPU 处理器上运行测试)。
你能给我解释一下吗?
编码:

package main

import (
    "fmt"
    "time"
)

// Sum returns n by calculating 1+1+1+..
func Sum(n int64) int64 {
    ret := int64(0)
    for i := int64(0); i < n; i++ {
        ret += 1
    }
    return ret
}

func main() {
    n := int64(30000000000) // 30e9
    sum := int64(0)
    beginTime := time.Now()

    nWorkers := 4
    sumChan := make(chan int64, nWorkers)
    for i := 0; i < nWorkers; i++ {
        go func() { sumChan <- Sum(n / int64(nWorkers)) }()
    }
    for i := 0; i < nWorkers; i++ {
        sum += <-sumChan
    }

    fmt.Println("dur:", time.Since(beginTime))
    fmt.Println("sum:", sum)

    // Results on Intel Core i5-8265U (nWorkers,dur):
    // (1, 8s), (2, 4s), (4, 2s), (8, 2s). Why 8 CPUs still need 2s?
}

标签: goparallel-processing

解决方案


我在 8 CPU 处理器 i5-8265U 上运行测试

i5-8265U 不是 8 核 CPU,它是 4 核 8 线程 CPU:它有 4 个物理核心,每个核心可以通过超线程同时运行 2 个线程。

HT 的“性能优势”取决于工作负载,以及将来自一个线程的操作与另一个线程的计算“混合”的能力。这意味着如果你的 CPU 负载很高,超线程可能无法获得超过百分之几的运行时间,因此对整体性能的贡献不大。

此外,8265U 的标称频率为 1.6GHz,最大睿频为 3.9(4 核 3.7)。包括超线程在内的 CPU 满载也可能会进一步降低“涡轮增压上限”。您必须在运行期间检查 cpuinfo 状态才能看到。


推荐阅读