Noch kürzer Warten als Sleep(1)
-
Nö, macht er nicht (wäre auch dämlich...)
-
Also nochmal, jeder Windows taugliche PC, Celeron,Pentium etc., besitzt einen Hochauflösenden
Performance Counter, je mit unterschidlicher Frequenz, zwischen 0,1 und größer 3MHz. Um nun
das ganze zu nutzen, müssen wir die Frequenz auslesen mit QueryPerformanceFrequency() und setzen
eine Startzeit, also ab wann wir uns in die Zählung einklinken.LARGE_INTEGER PerformanceFrequenz; QueryPerformanceFrequency(&PerformanceFrequenz); LARGE_INTEGER StartZeit; QueryPerformanceCounter(&StartZeit);
Ach, lange Rede, kurzer Sinn hier die Funktion.
void SleepMicro(double WaitTime) { LARGE_INTEGER PerformanceFrequenz; QueryPerformanceFrequency(&PerformanceFrequenz); LARGE_INTEGER StartTime; QueryPerformanceCounter(&StartTime); LARGE_INTEGER CurrentTime; double TimeElapsed; while (TimeElapsed <= WaitTime) { QueryPerformanceCounter(&CurrentTime); TimeElapsed = (long double)(CurrentTime.QuadPart - StartTime.QuadPart)/((long double)PerformanceFrequenz.QuadPart); } }
Nun kann man die Funktion so Aufrufen: SleepMicro(0.004); wartet 0,004 Sekunden, giebt man nur eine 1 an, so wartet sie 1 Sekunde
So wenn jetzt noch nen Noob kommt und nach NOP fragt dann noppe ich nur noch Ostfriesenwitze hier.
-
@MiC++ha:
Nur als Anmerkung: das garantiert dir aber noch nicht das du nicht einfach mal für ein paar ms "Weggeschedulet" wirst
-
peterchen schrieb:
@MiC++ha:
Nur als Anmerkung: das garantiert dir aber noch nicht das du nicht einfach mal für ein paar ms "Weggeschedulet" wirstEs giebt für nichts eine Garantie.
aber für den Normalfall reicht das aus. Man kann das natürlich auch entsprechend Ausbauen, aber die frage ist: Wofür.
-
aber die frage ist: Wofür
eben
aber das werden wir wohl nie erfahren...
-
peterchen schrieb:
@MiC++ha:
Nur als Anmerkung: das garantiert dir aber noch nicht das du nicht einfach mal für ein paar ms "Weggeschedulet" wirstWindows ist ja auch kein Echtzeit-OS, so kleine Wartezeiten sind ja für nichts gut. Nicht mal in der Spieleprogrammierung wartet man Mikrosekunden.
MfG SideWinder
-
peterchen schrieb:
Nö, macht er nicht (wäre auch dämlich...)
Auch auf die Gefahr hin dass meine Frage genauso dämlich ist,aber warum wäre es denn dämlich wenn die NOP´s wegoptimiert werden?
Auf den ersten Blick erscheint es mir eigentlich sinnvoll wenn Anweisungen die nichts machen der Optimierung zum Opfer fallen.MfG Spacelord
-
Nee, die Frage isses nicht
Zwar ist die Optimierung von inline-assembly weit außerhalb des Standards, dem Compiler wäre es also nicht verboten.
Aber der einzige Zweck von NOP ist: nix machen. Wenn man ein NOP reinschreibt, hat man sich also was bei gedacht.
Übliche Anwendungsfälle sind: Warten auf externe Hardware, "Füllbyte" bei automatischer Codegenerierung / patchen. Wenn man für einen speziellen Prozessor optimiert, kann man mit einem geschickten NOP außerdem pipeline stalls und ungünstige pipeline-Zuordnung vermeiden - mit NOP kann es also sogar schneller sein.
-
Eigentlich suche ich eine Alternative zu Sleep() da ich gemerkt hab da Sleep sehr ungenau ist. Es wartet mal so mal so. Da muss es doch alternativen geben? Am besten welche die nicht viel CPU Auslastung brauchen.
-
Entweder du sagst Windows, dass du keine Rechenzeit abgeben willst und versuchst möglichst lang, dass dein Thread aktiv bleibt (100% Auslastung), oder du sagst eben Windows, dass es deinen Thread irgendwann wieder aktivieren soll (Sleep) - aber wie schon gesagt: Windows ist kein Echtzeit-Betriebssystem!
-
Die alternative "genauer und keien Rechenzeit" gibt es nicht (es sei denn, man schiebt Windows einen Echtzeit-Kernel unter)
Multimedia-Timer kommen noch am nächsten, aber schon mit merklicher Last für das System. Die Auflösung ist aber auch in ms.
Die Begrenzungen kommen nicht aus dem Sleep selbst, sondern dem Thread Scheduler. Sleep sagt dem Scheduler nur, das der thread für die nächsten N ms nicht geschedult werden soll.
Die generische Lösung bleibt Sleep. Wenn die Genauigkeit von Sleep ncith ausreicht, muß man halt erstmal fragen: warum.
-
peterchen schrieb:
Die alternative "genauer und keien Rechenzeit" gibt es nicht (es sei denn, man schiebt Windows einen Echtzeit-Kernel unter)
Multimedia-Timer kommen noch am nächsten, aber schon mit merklicher Last für das System. Die Auflösung ist aber auch in ms.
Die Begrenzungen kommen nicht aus dem Sleep selbst, sondern dem Thread Scheduler. Sleep sagt dem Scheduler nur, das der thread für die nächsten N ms nicht geschedult werden soll.
Die generische Lösung bleibt Sleep. Wenn die Genauigkeit von Sleep ncith ausreicht, muß man halt erstmal fragen: warum.
Warum? Ich programmiere ein Spiel mit Winapi und wenn ich keinen Sleep Befehl einbaue läuft ja alles megaschnell!
Ich hab gehört das man die 12ms Schritte von Sleep() auf 1 ms Schritte kürzen kann mit SetSystemTimeAdjustment() allerdings krieg ich da die Fehlermeldung dass der Client ein erforderliches recht nicht besitzt.
-
joomoo schrieb:
Ich programmiere ein Spiel mit Winapi und wenn ich keinen Sleep Befehl einbaue läuft ja alles megaschnell!
Vielleicht solltest du die Bewegungen in deinem Spiel von "Weg pro Frame" auf "Weg pro Zeit" umstellen. Dann bist du nämlich relativ unabhängig von der tatsächlichen Framerate.
-
joomoo schrieb:
Warum? Ich programmiere ein Spiel mit Winapi und wenn ich keinen Sleep Befehl einbaue läuft ja alles megaschnell!
Das macht man aber nicht mit sleep, denn jeder ausführungsblock kann unterschiedlich lange dauern und mit sleep() können keine Nachrichten verarbeitet werden.
Mach es so:
/* global */ bool ende = false; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { /* Spiel einrichten, bilder laden und so */ DWORD idle; /* die Spielschleife */ while (!ende) { idle = GetTickCount(); /* aktuellen Millisekundenstand hollen */ /* Nachrichten abhandeln */ while(PeekMessage(&messages, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&messages); DispatchMessage(&messages); } /* Spiel Code */ /* und nun die Frame Bremse */ while ((GetTickCount() - idle) < 40) /* 25 Frame Sekunde */ ; } }
So läuft es nun mit 25 Bilder Sekunde, wie beim Film
-
MiC++ha schrieb:
joomoo schrieb:
Warum? Ich programmiere ein Spiel mit Winapi und wenn ich keinen Sleep Befehl einbaue läuft ja alles megaschnell!
Das macht man aber nicht mit sleep, denn jeder ausführungsblock kann unterschiedlich lange dauern und mit sleep() können keine Nachrichten verarbeitet werden.
Mach es so:
/* global */ bool ende = false; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { /* Spiel einrichten, bilder laden und so */ DWORD idle; /* die Spielschleife */ while (!ende) { idle = GetTickCount(); /* aktuellen Millisekundenstand hollen */ /* Nachrichten abhandeln */ while(PeekMessage(&messages, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&messages); DispatchMessage(&messages); } /* Spiel Code */ /* und nun die Frame Bremse */ while ((GetTickCount() - idle) < 40) /* 25 Frame Sekunde */ ; } }
So läuft es nun mit 25 Bilder Sekunde, wie beim Film
Das hat ich auch schon gedacht, aber das geht nicht, da GetTickCount() genauso ungenau ist wie sleep! Ein Tick sind nur ungefähr 10 ms...
-
Eigentlich sollte man bei Games die Bewegungen unabhängig von den Frames, sondern abhängig von der Zeit machen.
Frame-Bremse sollte höchstens benutzt werden, wenn sonst bei schnellen Grakas einige Werte zu klein/zu groß werden um damit noch gescheit rechnen zu können...
...aber die Thematik gehört wohl eher ins Spiele/-Grafikprogrammierungs-Forum...
-
Ich brauche einfach nur einen Ersatz für Sleep() der mindestens ms genau ist...
-
Nein das brauchst du nicht. Hör auf uns.
-
MiC++ha hat doch schon eine Lösung mit Hilfe von QueryPerformanceCounter gepostet, oder funktionierte die nicht?!
-
flenders schrieb:
MiC++ha hat doch schon eine Lösung mit Hilfe von QueryPerformanceCounter gepostet, oder funktionierte die nicht?!
Doch das Funktioiert, nur unter 1000MHz kann mann keine hohe genauigkeit garantieren, aber wer hat weniger als 1000MHz außer meine Frau(500 Celeron)? :::Geitz ist geil:::
Ne mal genau gesagt, wir wissen nicht genau den Zusammenhang, den sagt er auch nichts da er sonst ins Spieleforum verschwindet, aber mit dieser "Wer wird Millionär" raterei, kommen wir auch nicht weiter.
Diese Spielschleife die ich anzeigte kann auch leicht mit QueryPerformanceCounter() verfeinert werden, die allgemeine Regel lautet ::Sleep() vermeiden, und das hat seine Gründe, aber wenn man QueryPerformanceCounter() benutzt auf (ab) einen 800MHz Rechner kann mann sich
schon in guter genauigkeit bewegen (je nach Prozess anzahl).
Solange wir keine genauen Infos haben, bringt das alles nichts, und ich denke wenn diese Infos kommen ist es Vermutlich doch was fürs Spieleforum.Genauer als Sleep
Auch dazu wurden gewisse Antworten gegeben, und bei spielen giebts keine Genauigkeit, sondern so ne Art Ablauf Perfomance, wenn dein Spiel bei dir gut und Genau läuft, muß es nicht gleich auch bei mir genauso gut laufen, und schon gar nicht mit "Schlafen".