go - 性能几乎以线性方式提高,将GOMAXPROCS从1增加到4,但此后保持平稳

标签 go

我正在研究具有8核的机器(带有“2,8 GHz Intel Core i7”处理器的Mac),可以看到正在运行fmt.Println(runtime.NumCPU())
我实现了一个非常简单的工作程序池模型,以同时处理一些进入该池的请求。进程类型为“CPU密集型”,我想对使用更多GO内核的性能有多大的了解。
所以代码如下

func Run(poolSize int, workSize int, loopSize int, maxCores int) {
    runtime.GOMAXPROCS(maxCores)

    var wg sync.WaitGroup
    wg.Add(poolSize)
    defer wg.Wait()

    // this is the channel where we write the requests for work to be performed by the pool
    workStream := make(chan int)

    // cpuIntensiveWork simulates an CPU intensive process
    var cpuIntensiveWork = func(input int) {
        res := input
        for i := 0; i < loopSize; i++ {
            res = res + i
        }
    }

    // worker is the function that gets fired by the pool
    worker := func(wg *sync.WaitGroup, workStream chan int, id int) {
        defer wg.Done()
        for req := range workStream {
            cpuIntensiveWork(req)
        }
    }

    // launch the goroutines of the pool
    for i := 0; i < poolSize; i++ {
        go worker(&wg, workStream, i)
    }

    // feed the workStream until the end and then close the channel
    for workItemNo := 0; workItemNo < workSize; workItemNo++ {
        workStream <- workItemNo
    }
    close(workStream)
}
基准是这些
var numberOfWorkers = 100
var numberOfRequests = 1000
var loopSize = 100000

func Benchmark_1Core(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Run(numberOfWorkers, numberOfRequests, loopSize, 1)
    }
}
func Benchmark_2Cores(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Run(numberOfWorkers, numberOfRequests, loopSize, 2)
    }
}
func Benchmark_4Cores(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Run(numberOfWorkers, numberOfRequests, loopSize, 4)
    }
}
func Benchmark_8Cores(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Run(numberOfWorkers, numberOfRequests, loopSize, 8)
    }
}
运行基准测试时,我注意到性能几乎从1核增加到2核再到4核呈线性增长。但是我从4核升级到8核的性能差异非常有限。
这是预期的行为吗?如果是这样,根本原因是什么?

最佳答案

有了多个核心,事情可能会变得有趣。最可能的解释是您没有八个核心,但是四个具有超线程的核心将为您带来更少的加速-有时根本没有。
另一个可能需要检查的解释是,每个线程都使用大量内存,并且您用完了缓存内存。否则您将达到内存带宽饱和的状态,此时没有任何处理器可以为您提供帮助。

关于go - 性能几乎以线性方式提高,将GOMAXPROCS从1增加到4,但此后保持平稳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64121524/

相关文章:

excel - 遍历golang中的列单元格并进行excelize

websocket - 如何在 GO 的 websocket 中保持连接

unit-testing - 如何在 golang 中对谷歌云存储进行单元测试?

go - 如何检查错误类型?

go - function() used as value 编译错误

postgresql - 使用 Gorm 插入和选择 PostGIS 几何

go - 递归结构反射错误 : panic: reflect: Field of non-struct type

golang regexp FindStringSubmatch() 不返回正确的最后一组

go - GRPC 消息结构

google-app-engine - 关于获取datastore的Cursor行为的问题