我使用go语言的go1.5.3 linux / amd64版本。我有一个go例程,执行一个需要一些时间的数学运算。每个例程都独立行动,不必阻止。
我的系统有12个核心。如果我产生12个例程,那么所有核心的平均使用率只需要高达31%。如果我使用24个例程,它会使所有核心的平均使用率达到49%。如果我使用240,我得到77%。 2400给了我76%。
显然,rand.Intn(j)操作正在减慢它的速度。没有它,核心将以100%运行。
func DoSomeMath() int {
k := 0
for i := 0; i < 1000; i++ {
j := i*i + 2
k += i * rand.Intn(j)
}
return k
}
如何在使用RNG时让程序以100%的速度使用所有核心?
答案 0 :(得分:1)
主要原因是,全局rand.*
使用互斥锁,因此在任何给定点上,您一次只能生成一个随机数。
@ peterSO的答案起作用的原因是因为现在没有互斥锁,而且每个例程只有1个生成器,但是如果2个或更多goroutine从精确的纳秒开始,你最终可能会出现重复状态,尽管不太可能。
看看here,了解全球兰特的工作原理。
答案 1 :(得分:0)
换句话说,有谎言,该死的谎言和基准。
尽管被问到,但您仍未发布重现问题所需的代码:How to create a Minimal, Complete, and Verifiable example.
这是一个可重现的基准测试,它使用PRNG,可以使你的CPU接近100%:
package main
import (
"math/rand"
"runtime"
"time"
)
func DoSomeCPU(done <-chan bool) {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
k := 0
for i := 0; i < 1000000; i++ {
j := i*i + 2
k += i * r.Intn(j)
}
_ = k
<-done
}
func main() {
numCPU := runtime.NumCPU()
runtime.GOMAXPROCS(numCPU)
done := make(chan bool, 2*numCPU)
for {
done <- true
go DoSomeCPU(done)
}
}
运行此代码后会得到什么结果?