2016-12-10 60 views
1

我需要一個golang代碼片段來增加CPU使用率,這是爲了測試運行我的服務的K8s羣集中的自動擴展,使用Go編寫的服務。我試着用下面顯示的計算Sqrt的循環並打印結果,但幾乎不能使用CPU。Golang代碼來增加CPU使用率

num += math.Sqrt(num) 
fmt.Println(num) 

這將是更好的,如果它不是一個無限循環,因爲我還需要停止在負載和測試縮放。

回答

1

這裏有一個小片斷,使用所有的內核寫入.字符/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) 
} 
+0

此代碼有競爭條件,訪問局部變量'keepGoing'不同步(使用'-race'選項來驗證)。更好地使用這種渠道。 – icza

+0

我沒有看到需要,因爲這個程序在睡眠之後立即退出。事實上,現在你提到它,即使'keepGoing'變量不需要,如果這個程序要作爲一個整體運行。 – noisypixy

+0

這是不正確的。事實上,你掌握了goroutine調度程序,如果主要的goroutine沒有在睡眠後安排好,你的app可能會「永遠」運行。 – icza

2

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 
    } 
} 
8

你並不真正需要的任何「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) 
+0

是的,如果試圖強調CPU,避免封鎖操作,只是做一個無限循環(可以取消)。 – eduncan911

+0

任何想法你將如何解決這個方法來擊中特定的目標%。就像如果你想模擬一個40%或85%的負載? – Futile32