在golang中,我的例程正在使用所有核心,但每个核心只占50%到75%

时间:2016-02-13 18:58:47

标签: go parallel-processing goroutine

我使用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%的速度使用所有核心?

2 个答案:

答案 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)
    }
}

运行此代码后会得到什么结果?

相关问题