2016-12-10 2 views
1

Ich brauche ein Golong-Code-Snippet, um die CPU-Auslastung zu erhöhen, dies ist die automatische Skalierung in einem K8s-Cluster mit Pod in Go. Ich habe versucht, mit einer Schleife Sqrt wie unten gezeigt zu berechnen und das Ergebnis zu drucken, aber es nutzt kaum die CPU.Golang-Code zur Erhöhung der CPU-Auslastung

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

Es wäre besser, wenn es nicht eine Endlosschleife ist da muss ich auch in der Last und Test Skalierung stoppen.

Antwort

1

Hier ist ein kleines Snippet, das . Zeichen /dev/null mit allen Kernen schreibt, und stoppt nach 10 Sekunden.

In meinem Fall wird in diesem fast 100% meiner Intel Core 2 Duo @ 2.20GHz, damit ich weiß nicht, wie es sich verhalten, wenn irgendwo mit höheren Spezifikationen ausgeführt, aber ich denke, die Zahl der goroutines Erhöhung würde machen.

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

Dieser Code hat Race Conditions, Zugriffe auf die lokale Variable 'keepGoing' sind nicht synchronisiert (mit der Option '-race' zur Überprüfung). Besser Kanäle für so etwas zu verwenden. – icza

+0

Ich sah nicht die Notwendigkeit, da dieses Programm direkt nach dem Schlaf beendet. In der Tat, jetzt, wo Sie es erwähnen, ist auch die "keepGoing" Variable nicht notwendig, wenn dieses Programm als Ganzes ausgeführt werden soll. – noisypixy

+0

Das ist nicht wahr. So wie es ist, sind Sie in den Händen des Goroutine Scheduler, und wenn die Haupt Goroutine nicht nach dem Schlaf geplant wird, könnte Ihre App laufen "für immer" .. – icza

2

noisypixy hat die richtige Idee mit allen Kernen verwenden, aber auf meiner Maschine es geschaffen, nur etwa 50% Last auf allen Prozessoren zu treffen. Ich glaube, das liegt daran, dass Prints langsam, aber nicht CPU-intensiv sind.

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

Sie wirklich nicht brauchen jede „CPU-intensive“ Berechnung, man muss nur vermeiden (wie Warten auf Daten über eine Netzwerkverbindung oder das Schreiben in eine Datei) zu blockieren, und Sie müssen mindestens so viele goroutines das tun so viele CPU-Kerne, die Sie haben (dies kann mit runtime.NumCPU() abgefragt werden). Die Verwendung von ist eine schlechte Idee, da sie möglicherweise auf eine Datei, eine Netzwerkverbindung usw. gerichtet ist und daher das Drucken darauf blockieren kann (E/A-Warte).

Verwenden Sie eine "endlose" Schleife, die nichts tut, außer zu überprüfen, ob es Zeit ist abzubrechen. Sie können dies mit einem einzelnen Kanal tun und ihn schließen, wenn Sie abbrechen möchten (Empfang auf einem geschlossenen Kanal kann sofort fortgesetzt werden, was den Nullwert des Elementtyps des Kanals ergibt), und Goroutines können dies unter Verwendung der select-Anweisung überprüfen mit einem default Zweig sonst würde es nur blockieren). Sie müssen nicht einmal die maximale Anzahl an CPUs festlegen, die gleichzeitig ausgeführt werden können (runtime.GOMAXPROCS()), da dies standardmäßig der Anzahl der verfügbaren Cores seit Go 1.5 entspricht. Einfachste Lösung:

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

Ja, wenn Sie versuchen, die CPU zu belasten, vermeiden Sie blockweise Operationen und machen Sie einfach eine Endlosschleife (die abgebrochen werden kann). – eduncan911

+0

Irgendeine Idee, wie Sie diesen Ansatz wählen würden, um ein bestimmtes Target% zu treffen. Wie wenn Sie eine Last von 40% oder 85% simulieren möchten? – Futile32

Verwandte Themen