Prozessorauslastung bei mehreren Threads



  • Hallo,

    ich habe nochmal eine Frage zu Threads. Ich habe neben meinem Hauptthread einen Workerthread erstellt. Als Priorität habe ich dem THREAD_PRIORITY_NORMAL gegeben. In diesem Worker werden innerhalb einer Schleife wiederholt Werte aus einer Messkarte ausgelesen. Die Oberfläche bleibt bedienbar, mittels einer Message kann ich diesen Ausleseprozess auch beenden.
    Jetzt habe ich im Taskmanager gesehen, dass nach Anlegen des 2. Threads die Prozessorauslastung auf 100% raufgeht. Kann man das irgendwie begrenzen?



  • Was willst Du denn? Soll der 2. Thread seine arbeit *ständig* machen oder nur *manchmal*?
    Wenn nur *manchmal*, dann kannst Du ja z.B. ein "Sleep(1)" einbauen... das wartet dann zwar ca. 12-15 ms, aber die Prozessorlast wird auf 0% gesenkt 😉
    Aber natürlich dauer Deine Berechnung (oder was Du da machst) *wesentlich* länger...



  • Oder mache ein Sleep(0) und wenn der Restrechner frei ist bekommt der task wieder ein Zeitfenster



  • user schrieb:

    Oder mache ein Sleep(0) und wenn der Restrechner frei ist bekommt der task wieder ein Zeitfenster

    Sleep(0) bringt bzgl. Prozessorlast überhaupt nix... die bleibt trotzdem bei 100%.



  • Jochen Kalmbach schrieb:

    Was willst Du denn? Soll der 2. Thread seine arbeit *ständig* machen oder nur *manchmal*?
    Wenn nur *manchmal*, dann kannst Du ja z.B. ein "Sleep(1)" einbauen... das wartet dann zwar ca. 12-15 ms, aber die Prozessorlast wird auf 0% gesenkt 😉
    Aber natürlich dauer Deine Berechnung (oder was Du da machst) *wesentlich* länger...

    Der Thread steuert einen Schrittmotor. Man schaltet einen Digitalausgang auf High, wartet eine Weile und schaltet dann wieder auf Low. Ist nicht so elegant gelöst, funktioniert aber. Blöd ist, dass die On-/Off-Zeiten in einem Bereich kleiner einer Millisekunde liegen. Womit sich das Sleep(1) schon mal erledigt hat. Die Delays werden mit Zählschleifen realisiert. Innerhalb dieser Schleifen wird eine Variable incrementiert, was natürlich etwas Zeit beansprucht und somit ein Delay kleiner 1 ms ermöglicht. Dieser Code ist nicht von mir, aber mir würde spontan auch nichts anderes einfallen.
    Aber bezogen auf ständig oder manchmal: Einmal angeschoben soll sich der Motor drehen. Es werden über diese Karte während dieser Routine noch drei Spannungswerte von Sensoren eingelesen und über eine Berechnung wird überprüft, ob das Abbruchkriterium erfüllt ist oder nicht. Wenn das der Fall ist soll der Thread verlassen werden.
    Könnte man das auch anders realisieren?



  • Jochen Kalmbach schrieb:

    user schrieb:

    Oder mache ein Sleep(0) und wenn der Restrechner frei ist bekommt der task wieder ein Zeitfenster

    Sleep(0) bringt bzgl. Prozessorlast überhaupt nix... die bleibt trotzdem bei 100%.

    Hast du es schon versucht? Das ein Programm Last verursacht ist nichts schlimmes. Dazu sind Computer da. Sleep(0) gibt das Zeitfenster an Windows zurück. Sollten andere Prozesse auch mehr Zeit brauchen ist Sleep(0) genau das richtige.
    Und wenn die Auslastung dann bei 50 - 60% liegt passt das.
    Insbesondere bei Netzwerksachen und Schleifen ist dies der Fall.
    Warum sollte man ein Programm anhalten wenn es nicht notwendig ist.

    @AndyDD
    Du wirst ein Windows nie dazu veranlassen können etwas im Millisekundentakt zu machen. Windows ist kein EchtzeitBS.
    Selbst ein Timer alle 10 Millisekunden bringt nichts weil Windows das garnicht kann den Windows selbst arbeitet garnicht in diesem Takt.



  • user schrieb:

    Jochen Kalmbach schrieb:

    user schrieb:

    Oder mache ein Sleep(0) und wenn der Restrechner frei ist bekommt der task wieder ein Zeitfenster

    Sleep(0) bringt bzgl. Prozessorlast überhaupt nix... die bleibt trotzdem bei 100%.

    Hast du es schon versucht? Das ein Programm Last verursacht ist nichts schlimmes. Dazu sind Computer da. Sleep(0) gibt das Zeitfenster an Windows zurück. Sollten andere Prozesse auch mehr Zeit brauchen ist Sleep(0) genau das richtige.
    Und wenn die Auslastung dann bei 50 - 60% liegt passt das.
    Insbesondere bei Netzwerksachen und Schleifen ist dies der Fall.
    Warum sollte man ein Programm anhalten wenn es nicht notwendig ist.

    Sleep(0) ist böse und du hast nix verstanden.
    Sleep(0) gibt immer nur an Tasks mit gleicher oder höherer Priorität ab, und das ist ein wichtiger Unterschied zu Sleep(1).
    Und nein, sinnlos in einem Busy-Loop laufen ist auch NICHT das wozu Computer da sind, sondern es IST was schlimmes.
    BTW: vielleicht solltest du mal drüber nachdenken was Hyperthreading bzw. Dual Core bedeutet wenn du schon "Auslastung bei 50-60%" schreibst. Gelle. Mit einer Schleife die nur durch Sleep(0) gebremst wird und sonst nix hast du auf jeden Fall 100%, garantiert. Und ja, ich habe es ausprobiert.

    EDIT: 100% Auslastung des Cores bzw. der logischen CPU. Wenn du 2 davon hast und nur einer ausgelastet ist zeigt der Task Manager natürlich 50% an... /EDIT

    Schreib bitte keine solchen Postings wenn du vom Thema keine Ahnung hast.



  • AndyDD schrieb:

    Man schaltet einen Digitalausgang auf High, wartet eine Weile und schaltet dann wieder auf Low. Ist nicht so elegant gelöst, funktioniert aber. Blöd ist, dass die On-/Off-Zeiten in einem Bereich kleiner einer Millisekunde liegen.

    Die *gewünschte* on/off Zeit oder die *max. erlaubte*?
    Wenn zweiteres, dann hast du sowieso ein Problem, denn das kannst du unter Windows nicht garantieren.



  • user schrieb:

    Jochen Kalmbach schrieb:

    user schrieb:

    Oder mache ein Sleep(0) und wenn der Restrechner frei ist bekommt der task wieder ein Zeitfenster

    Sleep(0) bringt bzgl. Prozessorlast überhaupt nix... die bleibt trotzdem bei 100%.

    Hast du es schon versucht? Das ein Programm Last verursacht ist nichts schlimmes. Dazu sind Computer da. Sleep(0) gibt das Zeitfenster an Windows zurück. Sollten andere Prozesse auch mehr Zeit brauchen ist Sleep(0) genau das richtige.
    Und wenn die Auslastung dann bei 50 - 60% liegt passt das.

    Hast Du es schon mal versucht?
    Die Last liegt aber bei 100% (mit einem Prozessor).



  • hustbaer schrieb:

    Sleep(0) ist böse und du hast nix verstanden.
    Sleep(0) gibt immer nur an Tasks mit gleicher oder höherer Priorität ab...

    du hast es auch nicht verstanden :p
    Sleep(0) gibt nur rechenzeit an threads mit gleicher prio ab. die höher priorisierten werden sowieso bevorzugt, ob mit oder ohne Sleep(0)...

    hustbaer schrieb:

    Und nein, sinnlos in einem Busy-Loop laufen ist auch NICHT das wozu Computer da sind, sondern es IST was schlimmes.

    schlimm in bezug auf energieverbrauch, oder warum sonst noch?



  • Auch ihr könnt nicht alles Wissen.
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39041.html

    In dem Thread wurde auch nichts von Dualcore geschrieben.



  • pale dog schrieb:

    hustbaer schrieb:

    Sleep(0) ist böse und du hast nix verstanden.
    Sleep(0) gibt immer nur an Tasks mit gleicher oder höherer Priorität ab...

    du hast es auch nicht verstanden :p
    Sleep(0) gibt nur rechenzeit an threads mit gleicher prio ab. die höher priorisierten werden sowieso bevorzugt, ob mit oder ohne Sleep(0)...

    Doch, verstanden schon, hab aber nicht daran gedacht beim schreiben 😉

    hustbaer schrieb:

    Und nein, sinnlos in einem Busy-Loop laufen ist auch NICHT das wozu Computer da sind, sondern es IST was schlimmes.

    schlimm in bezug auf energieverbrauch, oder warum sonst noch?[/quote]
    Ja, z.B. das. Ich mag es z.B. nicht wenn mein Lüfter hochdreht und ich anfange ihne zu hören. Auf Notebooks im Akkubetrieb auch ganz toll sowas 😉



  • So, nun melde ich mich mal wieder zu Wort. Was zwei Tage Urlaub alles so ausmachen können.

    hustbaer schrieb:

    AndyDD schrieb:

    Man schaltet einen Digitalausgang auf High, wartet eine Weile und schaltet dann wieder auf Low. Ist nicht so elegant gelöst, funktioniert aber. Blöd ist, dass die On-/Off-Zeiten in einem Bereich kleiner einer Millisekunde liegen.

    Die *gewünschte* on/off Zeit oder die *max. erlaubte*?
    Wenn zweiteres, dann hast du sowieso ein Problem, denn das kannst du unter Windows nicht garantieren.

    Das weiß ich selbst. Generell arbeiten Timer im unteren Zeitbereich wesentlich unzuverlässiger. Ist für meine Anwednung aber egal. Der Motor soll einen Schritt machen, danach sind drei Messwerte zu erfassen, es folgt eine Berechnung und es wird ein Analogwert wieder ausgegeben. Sollten die Vorgaben erfüllt sein wird der Vorgang abgebrochen ansonsten wird wieder ein Schritt gemacht und das Spiel beginnt von vorn. Wenn zwischen den Schritte zeitlich kleine Abweichungen auftreten ist das nicht schlimm.
    Sleep(0) hatte ich schon probiert, bei Sleep(1) läuft der Motor zu langsam.
    Aber meine Frage war am Anfang: Kann man die Prozessorlast begrenzen, so dass z.B. die Anwendung maximal 80% den Prozessor auslastet?


  • Mod

    Ja! Mein Laptop oder mein Desktop zieht bei solchen mies programmierten Programmen sofort die Lüfterdrehzahl hoch...

    Warum? Nur weil 100% der prozessor Zeit für das pollen eines unisnnigen Status verschwendet werden.



  • Martin Richter schrieb:

    Ja! Mein Laptop oder mein Desktop zieht bei solchen mies programmierten Programmen sofort die Lüfterdrehzahl hoch...

    Warum? Nur weil 100% der prozessor Zeit für das pollen eines unisnnigen Status verschwendet werden.

    Ich weiß selbst das das nicht sauber ist. Aber hast Du eine andere Idee? Da hat sich ja schon mal jemand dran versucht und ich soll (oder muss) das jetzt fertig machen. Problem ist eben, dass ich den Ausgang eine bestimmte Zeit auf High-Level lassen muss, da sonst die Schrittmotorkarte den Impuls nicht erkennt bzw. die Messkarte den nicht sauber rausgibt.
    Außerdem läuft das Programm auf einem IPC. Der ist in einer Maschine eingebaut und läuft immer mit maximaler Lüfterdrehzahl....



  • Du kannst timeBeginPeriod(1) + Sleep(1) versuchen.
    Wenn das zu langsam ist mach es mit Sleep(0).
    Wenn das immer noch zu langsam ist mach es ganz ohne Sleep().

    Ich will niemandem verbieten Sleep(0) oder gar Loops ohne jegliche Pause zu verwenden. Ich finde es nur nicht richtig dass immer wieder kompletter Unfug über Sleep(0) gepostet wird. Und ich finde die Einstellung "is doch wurscht wenn ich sinnlos Rechenzeit verbrate" die von manchen vertreten wird zum kotzen.

    Wenn es allerdings einen guten Grund gibt einen Sleep(0) Loop zu verwenden, und nochdazu kein anderes Programm gestört wird, dann habe ich sicher nix dagegen und werde auch nicht versuchen es jmd. auszureden.



  • Sleep(0) ist keine Lösung für Profis. Aber auch ich habe schon bei Netzwerksoftware welche Dateien empfangen Sleep(0) eingebaut und die Last ist von 100% auf 5% gesunken.
    Es kommt da auch immer auf die Art Software an.
    Einen Schrittmotor mit 1ms anzusteuern geht unter Windows eh nicht. Da braucht es andere BS. Ich habe es mir nicht genau gemerkt aber RenéG hat damals was von ca. 18ms geschrieben was das minimum ist wo Windows zumindest vielleicht einen Auslösen könnte. Windows ich eben kein Echtzeit-BS.



  • @Unix-Tom:

    Also mit "timeBeginPeriod(1);" bekomme ich auf meinem Windows XP PRO SP2 eine Auflösung von ~2ms für Sleep() (1000 Durchläufe von Sleep(1) dauern ~195ms). Ohne "timeBeginPeriod(1);" dauert 1x Sleep(1) etwa 16ms.

    Einen Schrittmotor mit ~1ms Delay anzusteuern geht unter Windows auch ganz gut, solange es eben keine max. Zeit gibt die nicht überschritten werden darf. Die min. Zeit kann man eigentlich ganz gut mit QueryPerformanceCounter garantieren.

    Dass man damit das System herprügelt ist klar, aber wenn das Kastl sonst nix tut sollte es egal sein.

    Dass die bessere Lösung wahrscheinlich ein kleiner Microkontroller wäre den man z.B. an die serielle Schnittstelle oder per USB anhängen kann (irgendwas ala BASIC Briefmarke) ist auch klar.



  • Unix-Tom schrieb:

    Sleep(0) ist keine Lösung für Profis. Aber auch ich habe schon bei Netzwerksoftware welche Dateien empfangen Sleep(0) eingebaut und die Last ist von 100% auf 5% gesunken.

    Sleep(0) macht rein gar nichts (es legt Dein Thread nur in der Queue von ganz vorne nach ganz hinten; wenn Du aber der einzige in der Queue bist, kommst Du sofort wieder dran)! Die "Last" bleibt bei 100%!
    Du meinstest wohl ein "Sleep(1)"...



  • Guten Morgen. Das ist sicher alles richtig was ihr da sagt, beantwortet aber meine Fragestellung nicht. Sicher sollte man einen µC oder eine SPS zur Steuerung verwenden. Aber ihr wisst ja wie das ist wenn man ein Projekt übernimmt: gewisse Teile muss man aus irgendwelchen Gründen übernehmen und hat dann ein Haufen Ärger damit. Außerdem haben diese IPCs keine USB-Schnittstelle und die zwei seriellen Ports sind schon mit anderen Geräten belegt. Ich habe nie behauptet das ich irgendwelche Zeiten garantieren will oder muss und mir ist auch klar, dass Zeiten unter 20 ms kritisch sind bzw. auch darüber nie garantiert werden können da Windows kein Echtzeit-BS ist.

    @hustbaer: Wie soll ich denn QueryPerformanceCounter verwenden? Wenn ich das richtig verstanden habe gibt der doch die Anzahl der Ticks wieder, die seit dem Systemstart vergangen sind. Kann man das als Ersatz für die Zählschleifen verwenden? Ich hab irgendwo gelesen das da Auflösungen bis 1 µs möglich sind, da die Taktfrequenz dieses Hardwarecounters irgendwo bei 3,19 MHz liegen soll. Wenn dem so ist dann wäre zumindest das Programm unabhängig vom Prozessortakt. Bei den Zählschleifen ist das Verhalten ja rechnerabhängig, bei höheren Prozessorfrequenzen muss man ja die variable für die Abbruchbedingung erhöhen. Bleibt immer noch das Problem mit der Begrenzung der Prozessorauslastung.


Anmelden zum Antworten