我正在研究具有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/