Ich arbeite in einer wissenschaftlichen Einrichtung, und eine der Aufgaben, an denen ich gerade arbeite, umfasst das Ausführen von Simulationen und die Ausgabe der Daten, die von der Festplatte auf Festplatte erzeugt werden. Wenn ich "on-the-fly" sage, meine ich, dass das Programm selbst jede Sekunde Daten auf die Festplatte spuckt. Diese Simulationen sind rein in Single Thread C ++ geschrieben und werden auf einem Mac Pro ausgeführt. Die relevanten Spezifikationen dieses Mac sind wie folgt:
OSX Version: 10.6.8
Model Name: Mac Pro
Model Identifier: MacPro4,1
Processor Name: Quad-Core Intel Xeon
Processor Speed: 2.66 GHz
Number Of Processors: 2
Total Number Of Cores: 8
Die Intel Xeons sind für bis zu 8 virtuelle Kerne mit Hyper-Threading versehen
Ich führe meine Simulationen in einer einfachen SH-Datei mit der folgenden Syntax aus:
nohup simulation1.o configfile 2> /dev/null > /dev/null &
nohup simulation2.o configfile 2> /dev/null > /dev/null &
und so weiter...
Die Verwendung von nohup bedeutet, dass ich mich bei Remote-Arbeiten nicht um zufällige Verbindungsabbrüche kümmern muss.
Wenn ich mich anschaue ps
Nach dem Ausführen von 10 Simulationen mit meiner bash-Datei stelle ich fest, dass die Prozesse in der Spalte STATE regelmäßig von "Laufen" zu "Stecken" wechseln. Darüber hinaus würde ich erwarten, dass die CPU-Auslastung für jeden Prozess 100% beträgt, aber stattdessen jeder Prozess etwa 28% beträgt. (Ich gehe davon aus, dass die CPU-Auslastung für jeden Prozess 100% beträgt. Wenn ich nur eine dieser Simulationen durchführe, ist die CPU-Spalte maximal 100%, zusätzlich zu der Tatsache, dass die Kerne Hyperthreading aufweisen. Dies sind sehr CPU-lastige Simulationen .)
Weiß jemand, was los ist? Speziell:
- Was bedeutet "stecken" in Bezug auf
ps
- Warum ist die CPU nicht für jeden Prozess voll ausgelastet?
Ich würde mich sehr über eine Hilfe freuen.
Antworten:
Ich habe mein Problem behoben. Es stellte sich als ziemlich subtil heraus, aber dank Ozair traf er den Nagel auf den Kopf. Meine spezifische Simulation nicht lesen sehr viele Daten (nur die Initialisierungsparameter), verbraucht aber viel Zeit, um berechnete Daten auszuspucken. Die grobe Art und Weise, die ich ursprünglich implementiert habe, bezieht sich auf den Standard C ++
file.open("tobewritten.dat")
ist selbst für sich genommen sehr langsam, aber wenn mehrere Instanzen ausgeführt werden, müssen die einzelnen Instanzen auf der Festplatte für 'Schreibzeit' warten.Ich habe einige spezifische Lektionen gelernt:
cout << std::endl
spült den Puffer bei Gebrauch; Wenn der Puffer nicht voll ist, wird der schnellere Schreibvorgang in den RAM nicht optimal genutzt. Benutzen"\n"
und schließen Sie die Datei am Ende. c ++ behandelt den Puffer auf die Festplatte, wenn er voll ist.Beim gleichzeitigen Schreiben mehrerer massiver Dateien (GBs) ist es am besten, den Puffer manuell anzugeben. Im Moment habe ich den Puffer auf 50 MB gesetzt. Die Verwendung großer Puffer bedeutet, dass Ihr System mehr Zeit zwischen dem RAM und der CPU aufbringt und nur im Abstand von 50 MB auf die Festplatte (das langsame Bit) speichert
Nicht einmal verwenden
cout
in die Datei schreiben. Es ist langsamer alssprintf
und seine Varianten.Mit den oben beschriebenen Methoden habe ich von 28% CPU-Auslastung für jeden Prozess zu 100% CPU-Auslastung gewechselt. Der "steckenbleibende" STATE erscheint nicht mehr.
quelle