Prozessorauslastung bei mehreren Threads
-
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.
-
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.
-
AndyDD schrieb:
@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.
Das einfachste ist Du fragst vorher mittels QueryPerformanceFreuqency wie viele Ticks eine Sekunde sind

-
Jochen Kalmbach schrieb:
AndyDD schrieb:
@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.
Das einfachste ist Du fragst vorher mittels QueryPerformanceFreuqency wie viele Ticks eine Sekunde sind

Also so hier:
LONGLONG Frequency, CurrentTime, LastTime; double TimeElapsed, TimeScale; bool CounterAvailable = false; if (QueryPerformanceFrequency((LARGE_INTEGER*)&Frequency)) { CounterAvailable = true; TimeScale = 1.0/Frequency; QueryPerformanceCounter((LARGE_INTEGER*) &LastTime); } else { LastTime = timeGetTime(); TimeScale = 0.001; } if (CounterAvailable) { QueryPerformanceCounter((LARGE_INTEGER*) &CurrentTime); } else CurrentTime = timeGetTime(); TimeElapsed = (CurrentTime-LastTime)*TimeScale; LastTime=CurrentTime;Und damit schafft man Auflösungen kleiner 1 ms? Dann könnte man ja in einer do-while-Schleife QueryPerformanceCounter und die Differenz zum ersten Wert bilden, bis eine gewisse Anzahl von Ticks erreicht worden ist. Oder man rechnet alternativ mit Zeiten. Sehe ich das so richtig?
-
AndyDD schrieb:
Und damit schafft man Auflösungen kleiner 1 ms? Dann könnte man ja in einer do-while-Schleife QueryPerformanceCounter und die Differenz zum ersten Wert bilden, bis eine gewisse Anzahl von Ticks erreicht worden ist. Oder man rechnet alternativ mit Zeiten. Sehe ich das so richtig?
Genau! Ist das nicht Toll!?
Der Nachteil ist: Dein Rechner ist halt zu 100% ausgelastet...
-
Genau. Allerdings solltest du bei QueryPerformanceCounter aufpassen. Wir hatten unlängst erst einen Thread wo jmd. geschrieben hat dass die Werte bei ihm z.T. "zurückgesprungen" sind, die gemessene Zeit sozusagen negativ war. Anscheinend kann das bei AMD Systemen unter gewissen Umständen passieren.
Und ich selbst habe erlebt dass sogar auf Intel Systemen die Werte z.T. etwas "springen" (wenn auch nie zurück).Du solltest also wenn du QueryPerformanceCounter verwendest entweder zusehen dass das Programm auf "kontrollierter" Hardware läuft (=nur mit Komponenten von denen bekannt ist dass sie keine Probleme machen), und vielleicht auch nicht ganz an die Grenzen des Schrittmotors gehen, sondern ein paar Prozent Spielraum lassen.
Weiters hab' ich in einigen Codes gesehen dass timeGetTime und QueryPerformanceCounter parallel verwendet werden. Dabei wird timeGetTime z.B. verwendet um zu checken ob das was QueryPerformanceCounter zurükliefert stimmen kann, um Probleme zu vermeiden wenn QueryPerformanceCounter von einem Moment auf den anderen einen Riesen "Sprung in der Zeit" meldet (=viel mehr als die wirklich vergangene Zeit).
So sollte sich trotz der "unzulänglichkeiten" von QueryPerformanceCounter eine Clock basteln lassen die gut geringe Zeitspannen abdecken kann aber trotzdem nie "wild in der Gegend rumspringt".
-
Jochen Kalmbach schrieb:
AndyDD schrieb:
Und damit schafft man Auflösungen kleiner 1 ms? Dann könnte man ja in einer do-while-Schleife QueryPerformanceCounter und die Differenz zum ersten Wert bilden, bis eine gewisse Anzahl von Ticks erreicht worden ist. Oder man rechnet alternativ mit Zeiten. Sehe ich das so richtig?
Genau! Ist das nicht Toll!?
Der Nachteil ist: Dein Rechner ist halt zu 100% ausgelastet...Ja das war er ja vorher mit der Zählschleife auch. Bleibt jetzt nur noch die Frage nach der Begrenzung. Aber anscheinend gehts nicht...
hustbaer schrieb:
Du solltest also wenn du QueryPerformanceCounter verwendest entweder zusehen dass das Programm auf "kontrollierter" Hardware läuft (=nur mit Komponenten von denen bekannt ist dass sie keine Probleme machen), und vielleicht auch nicht ganz an die Grenzen des Schrittmotors gehen, sondern ein paar Prozent Spielraum lassen.
Was verstehst Du denn unter kontrollierter Hardware? Ich hab in der Kiste ein Intelsystem mit einem Celeron, der dürfte ja nach Deinen Aussagen das alles mitmachen, oder?
-
Ich meine damit dass dann z.B. nicht nächstes Jahr auf einmal ein AMD verwendet wird weils billiger ist, oder grad nix anderes verfügbar war.
Kontrolliert im Sinne von "nicht einfach irgendwas".
Unterstützt wird QueryPerformanceCounter sowieso auf allen aktuellen Systeme, bloss die Genauigkeit ist eben sehr untershiedlich, vor allem auf Systemen die die Taktfrequenz dynamisch regeln und mehrere Cores/CPUs haben.