在Go语言中的并发 – 使用不同数量的CPU需要相同的时间

huangapple go评论72阅读模式
英文:

concurrency in go -Taking same time with different no of CPU

问题

我正在运行一个并发的Go程序,根据下面的两个案例观察到,无论使用多少个CPU,执行时间都是相同的。

案例1:当cpuUsed = 1时,

程序执行时间为3m20.973185s。

当我增加使用的CPU数量时,

案例2:当cpuUsed = 8时,

程序执行时间为3m20.9330516s。

请查看以下Go代码以获取更多详细信息。

package main

import (
	"fmt"
	"math/rand"
	"runtime"
	"sync"
	"time"
)

var waitG sync.WaitGroup
var cpuUsed = 1
var maxRandomNums = 1000

func init() {
	maxCPU := runtime.NumCPU() //它将给出最大的CPU数量 :)

	cpuUsed = 8 //对于1和8,花费的时间相同
	runtime.GOMAXPROCS(cpuUsed)

	fmt.Printf("CPU数量(总共=%d - 使用=%d)\n", maxCPU, cpuUsed)
}

func main() {

	start := time.Now()
	ids := []string{"rotine1", "routine2", "routine3", "routine4"}

	waitG.Add(4)
	for i := range ids {
		go numbers(ids[i])
	}
	waitG.Wait()

	elapsed := time.Since(start)
	fmt.Printf("\n程序执行时间为%s。\n", elapsed)
}

func numbers(id string) {
	rand.Seed(time.Now().UnixNano())
	for i := 1; i <= maxRandomNums; i++ {
		time.Sleep(200 * time.Millisecond)
		fmt.Printf("%s-%d  ", id, rand.Intn(20)+20)

	}
	waitG.Done()
}
英文:

I am running a go concurrent program with the below two case and observed that It is taking same time irrespective of no of CPU it using while execution.

Case1: When cpuUsed = 1

program took 3m20.973185s.

when I am increasing the no of CPU used.

Case2: when cpuUsed = 8

program took 3m20.9330516s. 

Please find the below Go code for more details.

package main

import (
	&quot;fmt&quot;
	&quot;math/rand&quot;
	&quot;runtime&quot;
	&quot;sync&quot;
	&quot;time&quot;
)

var waitG sync.WaitGroup
var cpuUsed = 1
var maxRandomNums = 1000


func init() {
	maxCPU := runtime.NumCPU() //It&#39;ll give us the max CPU :)

	cpuUsed = 8 //getting same time taken for 1 and 8
	runtime.GOMAXPROCS(cpuUsed)

	fmt.Printf(&quot;Number of CPUs (Total=%d - Used=%d) \n&quot;, maxCPU, cpuUsed)
}

func main() {

	start := time.Now()
	ids := []string{&quot;rotine1&quot;, &quot;routine2&quot;, &quot;routine3&quot;, &quot;routine4&quot;}

	waitG.Add(4)
	for i := range ids {
		go numbers(ids[i])
	}
	waitG.Wait()

	elapsed := time.Since(start)
	fmt.Printf(&quot;\nprogram took %s. \n&quot;, elapsed)
}

func numbers(id string) {
	rand.Seed(time.Now().UnixNano())
	for i := 1; i &lt;= maxRandomNums; i++ {
		time.Sleep(200 * time.Millisecond)
		fmt.Printf(&quot;%s-%d  &quot;, id, rand.Intn(20)+20) 

	}
	waitG.Done()
}

答案1

得分: 1

你会发现:

总时间(3分20秒)= 200秒 = sleep(200毫秒) * 循环次数(1000)

让我们简化你的代码并关注CPU使用率:

  1. 移除不使用CPU的Sleep。
  2. fmt.Println作为stdio,不使用CPU。
  3. 随机数没有做任何事情,只是引入了不确定性,移除它。
  4. goroutine中唯一消耗CPU的代码是"rand.Intn(20)+20",将其变为常量相加。
  5. 增加"maxRandomNums"的值。

然后你的代码将变成这样,再次运行它:

package main

import (
	"fmt"
	"runtime"
	"sync"
	"time"
)

var waitG sync.WaitGroup
var cpuUsed = 1
var maxRandomNums = 1000000000

func init() {
	maxCPU := runtime.NumCPU() //It'll give us the max CPU :)

	cpuUsed = 8 //getting same time taken for 1 and 8
	runtime.GOMAXPROCS(cpuUsed)

	fmt.Printf("Number of CPUs (Total=%d - Used=%d) \n", maxCPU, cpuUsed)
}

func main() {

	start := time.Now()
	ids := []string{"rotine1", "routine2", "routine3", "routine4"}

	waitG.Add(4)
	for i := range ids {
		go numbers(ids[i])
	}
	waitG.Wait()

	elapsed := time.Since(start)
	fmt.Printf("\nprogram took %s. \n", elapsed)
}

func numbers(id string) {
	// rand.Seed(time.Now().UnixNano())
	for i := 1; i <= maxRandomNums; i++ {
		// time.Sleep(200 * time.Millisecond)
		// fmt.Printf("%s-%d  ", id, rand.Intn(20)+20)
		_ = i + 20

	}
	waitG.Done()
}
英文:

you will find out:

total time (3 min 20s) = 200s = sleep(200ms) * loops(1000)

Let's simplify your code and focus on CPU usage:

  1. Remove the Sleep, which does not use the CPU at all
  2. fmt.Println as a stdio, does not use the CPU
  3. Random number did nothing but introduce uncertainty into the program, remove it
  4. The only code that takes CPU in the goroutine is the "rand.Intn(20)+20", making it a constant addition
  5. Increase the "maxRandomNums"

then your code will be like this, run it again

package main

import (
	&quot;fmt&quot;
	&quot;runtime&quot;
	&quot;sync&quot;
	&quot;time&quot;
)

var waitG sync.WaitGroup
var cpuUsed = 1
var maxRandomNums = 1000000000

func init() {
	maxCPU := runtime.NumCPU() //It&#39;ll give us the max CPU :)

	cpuUsed = 8 //getting same time taken for 1 and 8
	runtime.GOMAXPROCS(cpuUsed)

	fmt.Printf(&quot;Number of CPUs (Total=%d - Used=%d) \n&quot;, maxCPU, cpuUsed)
}

func main() {

	start := time.Now()
	ids := []string{&quot;rotine1&quot;, &quot;routine2&quot;, &quot;routine3&quot;, &quot;routine4&quot;}

	waitG.Add(4)
	for i := range ids {
		go numbers(ids[i])
	}
	waitG.Wait()

	elapsed := time.Since(start)
	fmt.Printf(&quot;\nprogram took %s. \n&quot;, elapsed)
}

func numbers(id string) {
	// rand.Seed(time.Now().UnixNano())
	for i := 1; i &lt;= maxRandomNums; i++ {
		// time.Sleep(200 * time.Millisecond)
		// fmt.Printf(&quot;%s-%d  &quot;, id, rand.Intn(20)+20)
		_ = i + 20

	}
	waitG.Done()
}

huangapple
  • 本文由 发表于 2022年1月18日 17:25:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/70753152.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定