我需要一個golang代碼片段來增加CPU使用率,這是爲了測試運行我的服務的K8s羣集中的自動擴展,使用Go編寫的服務。我試着用下面顯示的計算Sqrt的循環並打印結果,但幾乎不能使用CPU。Golang代碼來增加CPU使用率
num += math.Sqrt(num)
fmt.Println(num)
這將是更好的,如果它不是一個無限循環,因爲我還需要停止在負載和測試縮放。
我需要一個golang代碼片段來增加CPU使用率,這是爲了測試運行我的服務的K8s羣集中的自動擴展,使用Go編寫的服務。我試着用下面顯示的計算Sqrt的循環並打印結果,但幾乎不能使用CPU。Golang代碼來增加CPU使用率
num += math.Sqrt(num)
fmt.Println(num)
這將是更好的,如果它不是一個無限循環,因爲我還需要停止在負載和測試縮放。
這裏有一個小片斷,使用所有的內核寫入.
字符/dev/null
,和10秒後停止。
在我的情況下,該使用我英特爾Core 2 Duo @ 2.20GHz幾乎100%,所以我不知道有更高規格的地方執行時將如何表現,但我想提高夠程的數量將做。
package main
import (
"fmt"
"os"
"runtime"
"time"
)
func main() {
f, err := os.Open(os.DevNull)
if err != nil {
panic(err)
}
defer f.Close()
n := runtime.NumCPU()
runtime.GOMAXPROCS(n)
for i := 0; i < n; i++ {
go func() {
for {
fmt.Fprintf(f, ".")
}
}()
}
time.Sleep(10 * time.Second)
}
noisypixy與使用所有核心想法是正確的,但在我的機器上只設法擊中在所有處理器上約50%的負荷。我相信這是由於打印緩慢,但不是CPU密集型。
package main
import (
"runtime"
"time"
)
func main() {
n := runtime.NumCPU()
runtime.GOMAXPROCS(n)
quit := make(chan bool)
for i := 0; i < n; i++ {
go func() {
for {
select {
case <-quit:
return
default:
}
}
}()
}
time.Sleep(10 * time.Second)
for i := 0; i < n; i++ {
quit <- true
}
}
你並不真正需要的任何「CPU密集型」的計算,你只需要避免阻塞操作(如等待數據通過網絡連接或寫入文件),則至少需要儘可能多的goroutine可以完成儘可能多的CPU核心(可以使用runtime.NumCPU()
來查詢)。使用fmt.Println()
是一個壞主意,因爲它可能指向文件,網絡連接等,因此打印到它可能會阻塞(I/O等待)。
使用「無盡的」循環除了檢查是否該中止之外什麼也不做。您可以使用單個通道完成此操作,當您要中止時關閉它(在關閉的通道上接收可以立即進行,生成通道的元素類型的零值),並且goroutine可以使用select
語句(也是有一個default
分支,否則它只會阻塞)。您甚至不必設置可同時執行的最大CPU數(runtime.GOMAXPROCS()
),因爲這默認爲自Go 1.5以來的可用內核數。最簡單的解決方案:
done := make(chan int)
for i := 0; i < runtime.NumCPU(); i++ {
go func() {
for {
select {
case <-done:
return
default:
}
}
}()
}
time.Sleep(time.Second * 10)
close(done)
是的,如果試圖強調CPU,避免封鎖操作,只是做一個無限循環(可以取消)。 – eduncan911
任何想法你將如何解決這個方法來擊中特定的目標%。就像如果你想模擬一個40%或85%的負載? – Futile32
此代碼有競爭條件,訪問局部變量'keepGoing'不同步(使用'-race'選項來驗證)。更好地使用這種渠道。 – icza
我沒有看到需要,因爲這個程序在睡眠之後立即退出。事實上,現在你提到它,即使'keepGoing'變量不需要,如果這個程序要作爲一個整體運行。 – noisypixy
這是不正確的。事實上,你掌握了goroutine調度程序,如果主要的goroutine沒有在睡眠後安排好,你的app可能會「永遠」運行。 – icza