为了账号安全,请及时绑定邮箱和手机立即绑定

在 golang 中,我的 go 例程使用所有内核,但每个内核仅使用 50% 到 75%

在 golang 中,我的 go 例程使用所有内核,但每个内核仅使用 50% 到 75%

Go
慕尼黑8549860 2021-12-13 18:17:36
我使用的是 go 语言的 go1.5.3 linux/amd64 版本。我有一个执行需要一些时间的数学运算的 go 例程。每个 goroutine 独立运行,不必阻塞。我的系统有 12 个内核。如果我生成 12 个 go 例程,它只需要所有内核的平均使用率高达 31%。如果我使用 24 个 go 例程,它会使所有内核的平均使用率达到 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 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

换句话说,有谎言、该死的谎言和基准。


尽管被问到,您仍然没有发布重现问题所需的代码:如何创建最小、完整和可验证的示例。


这是一个可重复的基准测试,它使用 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)

    }

}

运行这段代码会得到什么结果?


查看完整回答
反对 回复 2021-12-13
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

主要原因是,全局rand.*使用互斥锁,因此在任何给定点,您一次只能生成一个随机数。

@peterSO 的答案有效的原因是因为现在没有互斥锁,并且每个例程有 1 个生成器,但是如果 2 个或更多 goroutines 在精确的纳秒内开始,您最终可能会得到重复的状态,尽管不太可能。

这里,看看全球兰特是如何运作的。


查看完整回答
反对 回复 2021-12-13
  • 2 回答
  • 0 关注
  • 186 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信