Alle CPUs nutzen friert Rechner ein



  • Okay, mir ist klar, dass das geht, klingt aber erstmal nicht für mich nach einer ausgeklügelten Lösung.

    Mir ist aufgefallen, dass auch mein UI-Prozess sehr langsam bzw. schlecht zu bedienen wird, wenn OpenMP eine Berechnung durchführt. Das ist ansich ja auch klar, aber wie löse ich es, dass ich bei vernünftiger UI-Reaktion trotzdem noch die CPUs möglichst effizient auslaste? Priorität mit OpenMP setzen ist ja anscheinend nicht drin (oder lange Zeit nicht gewesen, zumindest).



  • Also ich bin gespannt was noch für Antworten auf diese Frage kommen.

    Wir lassen typischerweise immer eine CPU noch für die UI und andere Dienste frei. Wir belagern also nur N-1 CPUs für Berechnungen.

    Sonst wäre wohl ein Time-Slice-Model notwendig. Unter Qt gibt es ein "processEvents" Methode, um die UI bei starken Berechnungen reaktiv zu halten.



  • Eisflamme schrieb:

    Okay, mir ist klar, dass das geht, klingt aber erstmal nicht für mich nach einer ausgeklügelten Lösung.

    wieso nicht? es macht genau das was deine anforderung war und wurde dafuer geschaffen. (threads die deiner meinung nach hoehere prioritaet haben sollten auch eine hoehere prioritaet zu geben und dennoch sonst die volle rechenleistung auszunutzen).

    Mir ist aufgefallen, dass auch mein UI-Prozess sehr langsam bzw. schlecht zu bedienen wird, wenn OpenMP eine Berechnung durchführt. Das ist ansich ja auch klar, aber wie löse ich es, dass ich bei vernünftiger UI-Reaktion trotzdem noch die CPUs möglichst effizient auslaste? Priorität mit OpenMP setzen ist ja anscheinend nicht drin (oder lange Zeit nicht gewesen, zumindest).

    wenn es zwei Prozesse sind und dein OS die time slices nicht vernuenftig hierarchisch aufteilt, musst du das selbst uebernehmen.


  • Mod

    Eisflamme schrieb:

    Okay, mir ist klar, dass das geht, klingt aber erstmal nicht für mich nach einer ausgeklügelten Lösung.

    Mir ist aufgefallen, dass auch mein UI-Prozess sehr langsam bzw. schlecht zu bedienen wird, wenn OpenMP eine Berechnung durchführt. Das ist ansich ja auch klar, aber wie löse ich es, dass ich bei vernünftiger UI-Reaktion trotzdem noch die CPUs möglichst effizient auslaste? Priorität mit OpenMP setzen ist ja anscheinend nicht drin (oder lange Zeit nicht gewesen, zumindest).

    Du hast vermutlich eine falsche Vorstellung von Prozesspriorität. Angenommen, du hast einen Prozess der sehr lange läuft (dein OpenMP-Programm), sagen wir es benötigt eine CPU-Stunde Rechenzeit. Gleichzeitig machst du irgendetwas mit deiner GUI, das 1 CPU-Minute Rechenzeit für die GUI benötigt. Angenommen, beide Programme haben die gleiche Priorität, wann ist das OpenMP-Programm fertig? Nach einer Stunde und einer Minute. Und deine GUI war in der Zeit grausam langsam zu bedienen, da sie immer auf das OpenMP-Programm warten musste. Angenommen die GUI hat hohe Priorität und/oder das OpenMP-Programm eine niedrige. Wann ist das OpenMP-Programm fertig? Nach 1 Stunde 1 Minute! Und deine GUI war die ganze Zeit knackig zu bedienen.

    Denn niedrige Priorität heißt nicht, dass ein Programm aktive gebremst wird, es heißt nur, dass es sich immer ganz hinten für Rechenzeit anstellen muss. Wenn aber niemand sonst in der Schlange steht, dann kommt es trotzdem sofort dran. Nur weil deine GUI-Anwendung immer sofort die Rechenzeit bekommt, die sie benötigt, benötigt sie dadurch nicht mehr Rechenzeit. Sie bekommt bloß die Rechenzeit sofort dann, wenn sie benötigt wird, anstatt irgendwann später.

    Folgerung: Lang laufende Hintergrundprozesse sollten immer niedrige Priorität haben, es macht für die Gesamtlaufzeit keinen Unterschied. Außerdem machen die ganzen feinen Abstufungen der Prozesspriorität, die manche Betriebssysteme anbieten (Linux bietet 40 Stufen!) für den Normalnutzer keinen Sinn. Man braucht eigentlich nur zwei*: Alle lang laufenden Hintergrundprozesse sollten die niedrigste Priorität haben und alle Vordergrundprozesse die normale Priorität.

    *: Der in diesem Forum nötige Disclaimer 🙄 : Es sind Ausnahmefälle konstruierbar, in denen man drei verschiedene Stufen sinnvoll einsetzen kann.



  • Hi,

    ihr habt Recht, das ist wirklich eine feine Sache, danke für die Erklärung.

    OpenMP-Threads kann man anscheinend über die BS-Befehle auch ganz gut umpriorisieren, dann werde ich dies wohl mal tun und noch ausführlicher testen 🙂

    Viele Grüße


  • Mod

    Da OpenMP ein high-level Threadingframework ist, sollte es eigentlich genug sein, einfach die Priorität des ganzen Prozesses (oder was auch immer das Äquivalent eines Unix-Prozesses bei deinem Betriebssystem ist) zu senken. Das auf Threadebene zu micromanagen klingt nach keiner guten Idee.



  • Eisflamme schrieb:

    gibt es einen Trick, wie man dafür sorgt, dass man nicht den ganzen PC einfriert, wenn man alle Threads für eine Berechnung nutzt?

    Wenn die Threads mit Priorität 0 laufen, und man nicht zu viele erzeugt (=nicht wesentlich mehr als man Hardware-Threads hat), dann muss man - zumindest unter Windows - gar nix tun. *

    Probier' einfach mal Prime95 oder sowas starten, mit so vielen Threads wie du Hardware-Threads hast. Wenn ich das mache, kann ich daneben "ganz normal" weiterarbeiten. Also es wird vermutlich alles messbar länger dauern, aber ich merke da wirklich keinen drastischen Slowdown.

    *: Haha, jetzt sollte ich vermutlich auch mal "disclaimern": Es gibt Fälle wo Windows quasi unbedienbar wird trotz dem man nicht mehr Threads laufen hat als die CPU Hardware-Threads kann, und trotz dem diese Threads alle die Basispriorität 0 haben. Wobei ich nicht genau weiss was der Grund ist. Aufgefallen ist mir das z.B. beim ollen Windows Taschenrechner. Wenn man für N Hardware-Threads N Instanzen vom Taschenrechner aufmacht, und auf jedem z.B. die Berechnung der Fakultät von z.B. einer Milliarde startet, dann "steht das System". So lange bis die Taschenrechner draufkommen dass sie die Fakultät von einer Milliarde gar nicht ausrechnen können. Unter Windows XP ging das sogar so weit dass DPCs um Ewigkeiten verzögert wurden (k.A. wie sich das unter Win 7/8/10 verhält, aber es würde mich nicht wundern wenn sich daran nix geändert hätte).

    Vielleicht sollte ich da mal mit dem Debugger gucken was der verdammte Taschenrechner da anstellt...

    Und natürlich nochwas: Wenn die Worker-Threads viel IO machen, dann können sie schlimmer bremsen. Vorausgesetzt die IOs gehen schnell genug und es gibt so viele Worker-Threads dass immer genug "runnable" sind um die CPU komplett auszulasten. Denn dann bekommen sie von Windows nen Prioritäts-Boost, jedes mal wenn ein IO fertig geworden ist. Und wenn sie schnell genug den nächsten IO machen, dann laufen sie effektiv immer geboostet. Und DANN kann man mit dem System auch nicht mehr ordentlich arbeiten.



  • Eisflamme schrieb:

    Mir ist aufgefallen, dass auch mein UI-Prozess sehr langsam bzw. schlecht zu bedienen wird, wenn OpenMP eine Berechnung durchführt. Das ist ansich ja auch klar,

    Naja, das sollte eben eigentlich nicht so sein.
    Es sei denn OpenMP gibt den Worker-Threads per Default ne richtig hohe Priorität.

    Kannst du mal gucken wie die Default-Priorität der OpenMP Threads ist?


  • Mod

    hustbaer schrieb:

    Eisflamme schrieb:

    Mir ist aufgefallen, dass auch mein UI-Prozess sehr langsam bzw. schlecht zu bedienen wird, wenn OpenMP eine Berechnung durchführt. Das ist ansich ja auch klar,

    Naja, das sollte eben eigentlich nicht so sein.
    Es sei denn OpenMP gibt den Worker-Threads per Default ne richtig hohe Priorität.

    Kannst du mal gucken wie die Default-Priorität der OpenMP Threads ist?

    In der Hinsicht ist auch sehr wichtig, welches Betriebssystem eingesetzt wird, mitunter sogar welche Version des Kernels. Bei Linux gab es beispielsweise vor ein paar Jahren größere Änderungen in Sachen der Priorität gebündelter Prozesse (wobei das aber eigentlich Threads nicht unbedingt betreffen sollte). Eben mit der Absicht, solche Aussetzer der GUI in Zukunft zu vermeiden.



  • Ja, stimmt, OS ist wichtig.

    Ich bin halt, da er Sleep(1) geschrieben hat, von Windows ausgegangen.

    (Gibt's unter Linux/BSD/... auch ne Sleep Funktion mit grossem "S"? Ich kenne zumindest keine. Wenn ich "sleep" lese denke ich halt einfach Linux/BSD/... und bei "Sleep" halt Windows.)



  • SeppJ schrieb:

    hustbaer schrieb:

    Eisflamme schrieb:

    Mir ist aufgefallen, dass auch mein UI-Prozess sehr langsam bzw. schlecht zu bedienen wird, wenn OpenMP eine Berechnung durchführt. Das ist ansich ja auch klar,

    Naja, das sollte eben eigentlich nicht so sein.
    Es sei denn OpenMP gibt den Worker-Threads per Default ne richtig hohe Priorität.

    Kannst du mal gucken wie die Default-Priorität der OpenMP Threads ist?

    In der Hinsicht ist auch sehr wichtig, welches Betriebssystem eingesetzt wird, mitunter sogar welche Version des Kernels. Bei Linux gab es beispielsweise vor ein paar Jahren größere Änderungen in Sachen der Priorität gebündelter Prozesse (wobei das aber eigentlich Threads nicht unbedingt betreffen sollte). Eben mit der Absicht, solche Aussetzer der GUI in Zukunft zu vermeiden.

    stimmt, bin deswegen damals bei meinem netbook auf fedora umgestiegen, war genau zu der zeit.
    unter winXP fing der mp3 player an zu stottern wenn ich kompilierte oder flash websites aufmachte, unter linux konnte lief alles besser, weil sie damals das scheduling erst pro process und dann auf threads aufgeteilt haben.

    window ist bis heute seltsam (wobei win10 merklich besser ist beim scheduling, finde ich), manchmal kann ich alles an rechenleistung ausnutzen und nebenbei youtube schauen, auf der anderen seite blockt manchmal ein prozess sogar den mauskursor.
    ich hab das gefuehl es hat ein wenig mit dem windows memory management zu tun. windows tagt wohl sporadisch immer mal memory pages als potentiel auslagbar und wenn man darauf zugreift, geht man in den page handler. das scheint sehr single threaded zu laufen und wenn mehrere threads page faults generieren, stallen sie wohl in einem zustande wo der scheduler die cores nicht re-usen kann.

    unter linux und osx hab ich das gefuehl dass der memory manager nichts mit auslagerung macht solange genug speicher vorhanden ist.



  • Hi,

    hustbaer: Richtig erkannt, ich nutze Windows. 🙂

    Da OpenMP ein high-level Threadingframework ist, sollte es eigentlich genug sein, einfach die Priorität des ganzen Prozesses (oder was auch immer das Äquivalent eines Unix-Prozesses bei deinem Betriebssystem ist) zu senken.

    Also wenn ich das hier nicht falsch verstehe, habe ich eigentlich einen Hauptthread, der auch die UI-Eventloop verwaltet, und der ruft OpenMP auf... wäre jetzt ziemlich sinnlos dessen Priorität zu senken, dann haben die OpenMP-Threads ja wieder dieselbe Priorität wie der Mainthread. UI ist QT, falls das was ändern sollte.

    Kannst du mal gucken wie die Default-Priorität der OpenMP Threads ist?

    Geschaut, haben alle THREAD_PRIORITY_NORMAL (0)

    Meine Threads nutzen kein I/O, jedenfalls nicht die, die ich zurzeit parallelisiert habe. Würde ich mit den anderen aber auch noch machen wollen.



  • Eisflamme schrieb:

    Hi,

    hustbaer: Richtig erkannt, ich nutze Windows. 🙂

    Da OpenMP ein high-level Threadingframework ist, sollte es eigentlich genug sein, einfach die Priorität des ganzen Prozesses (oder was auch immer das Äquivalent eines Unix-Prozesses bei deinem Betriebssystem ist) zu senken.

    Also wenn ich das hier nicht falsch verstehe, habe ich eigentlich einen Hauptthread, der auch die UI-Eventloop verwaltet, und der ruft OpenMP auf... wäre jetzt ziemlich sinnlos dessen Priorität zu senken, dann haben die OpenMP-Threads ja wieder dieselbe Priorität wie der Mainthread. UI ist QT, falls das was ändern sollte.

    du sprachst weiter oben davon dass du einen eigenen UI prozess hast

    dass auch mein UI-Prozess sehr langsam

    falls du nur einen thread hast der nicht mehr UI events verarbeitet weil er mit OpenMP berechnungen ausfuehrt, ist das eine ganz andere situation.



  • Hi,

    also das UI läuft im selben Prozess wie auch der Rest des Programms. Wollte damit nicht sagen, dass das Hauptprogramm einen Prozess erzeugt, welcher das UI verarbeitet, das geschieht hier nicht.

    OpenMP wird also aus demselben Prozess gestartet, der auch die Eventloop beinhaltet.



  • Dir ist aber schon klar dass OpenMP in dem Sinn synchron ist dass der Thread der auf OpenMP Konstrukte wie parallel for trifft erst weiter läuft wenn diese Konstrukte vollständig abgearbeitet wurden?



  • Eisflamme schrieb:

    OpenMP wird also aus demselben Prozess gestartet, der auch die Eventloop beinhaltet.

    was wuerde dann sowas bringen:

    Eisflamme schrieb:

    Setzt man einfach ein Sleep(1) oder so was in die Threads, um 100% Auslastung zu vermeiden?

    das ist ein wenig verwirrend.

    wenn openmp aus ist (also single threaded), funktioniert dann alles wie gewollt?



  • Ach sorry, ich hab einfach Mist erzählt... OpenMP läuft natürlich doch in einem ausgelagerten Thread, sonst wär ja ständig alles eingefroren. Soweit ich das verstehe habe ich dennoch nur einen Prozess, wenn man jetzt mal zwischen Thread und Prozess unterscheidet. Man sieht also im Taskmanager bei Windows unter Details nur einen Eintrag.

    Wenn ich den Prozess also langsamer machen würde, wäre das sinnlos, aber den Thread, der OpenMP ausführt, das wäre wohl sinnvoll. Und stimmt, das könnte ich dann tatsächlich einfach vor der OMP-Ausführung machen statt das jedem Thread einzeln anzutun. 🙂



  • Eisflamme schrieb:

    aber den Thread, der OpenMP ausführt, das wäre wohl sinnvoll. Und stimmt, das könnte ich dann tatsächlich einfach vor der OMP-Ausführung machen statt das jedem Thread einzeln anzutun. 🙂

    Naja OpenMP erzeugt ja haufenweise Worker.

    Und die erben vermutlich die Priorität nicht von irgendwo sondern werden eben vermutlich per Default Priorität 0 bekommen.

    Wie viele OpenMP Threads erzeugst du denn? Kann mir nämlich immer noch nicht ganz vorstellen warum OpenMP so reinhauen sollte dass die GUI kaum mehr erträglich funktioniert -- vorausgesetzt eben du machst nicht mehr OpenMP Threads als du Hardware-Threads hast.



  • oder einfach den UI thread hoeher prioritisieren, done.



  • Also ich las, dass der Erzeuger-Thread auch die Priorität für die OpenMP-Threads festlegt. Wenn ich seine Priorität also runtersetze, dürften die durch OpenMP erzeugten Threads auch niedriger priorisiert sein.

    Ich habe bislang omp_get_max_threads() genutzt. Auf meinem DualCore mit Hyperthreading, ergibt das vier. Ungeprüft und vermutet: Jetzt liegt wohl der UI-Thread auf Kern1 und die OpenMP-Threads verteilen sich wieder auf alle Kerne. Mit niedrigerer Priorität scheint es jetzt stabiler zu laufen. Alle vier Kerne sind stets zu 100% ausgelastet. Das stört ohne niedrigere Priorität das GUI und scheint eben auch andere Prozesse von Windows lahmzulegen, die gar nichts mit meiner Software zu tun haben (sehe ich erstmal als BS-Scheduling-Fail, aber gut). Testsystem war hier Windows 7. Ich selbst kann das gar nicht reproduzieren.

    Ich versuche den Tester auch gerade zu erreichen, um festzustellen, ob er mit dem Update, welches die Prioritäten runtersetzt, besser fährt. Es bleibt spannend.


Anmelden zum Antworten