Noch kürzer Warten als Sleep(1)



  • Sleep() täuscht aber nur eine 1-ms-Auflösung vor. Echte 1 ms-Schritte sind mit timeSetEvent() erreichbar.
    QueryPerformanceCounter() (mit QueryPerformanceFrequency()) hat eine Auflösung unter einer mikrosekunde, aber die Eigenverzögerung ist meist schon 3 bis 5 mikrosekunden groß.

    Außerdem funkt immer noch das OS dazwischen, verlassen kann man sich auf die Verzögerung nie.

    Blackbird



  • Warum und worauf willst du warten? Wie genau muß es sein?

    Bei Sleep() gibst du ms an, die echte Auflösung sind aber Cycles des Thread-Schedulers (12ms IIRC) - belastet aber die CPU nicht.

    timeSetEvent erlaubt millisekunden-genaue Auflösung, hat aber schon höhere Systemlast: verwendet u.a. einen thread (in dem wird deine Callback-Funktion dann auch aufgerufen).

    Mit QueryperformanceCounter / QueryperformanceFrequency kannst du eine Schlkeife basteln, die mindestens eine bestimmte Anzahl von micro/nanosekunden läuft. Allerdings ist die CPU dann unter last, und wenn ein anderer Thread gescheduled wird, bist du trotzdem erst nach ein paar ms wieder dran.



  • Ich tippe mal das du ein Spiel progen willst (wozu sonst die hohe Auflösung). In dem Fall würde ich dir zu QueryPerformanceCounter raten. Ich kenne eigentlich keine bessere Lösung für Spiele.



  • joomoo schrieb:

    Ich glaube meine Überschrift erklärt schon alles. Ich möchte weniger warten als eine Millisekunde.

    Sleep(0);

    😕



  • @hepi - das ist sogar sinnvoll - gibt das aktuelle time slice auf für den aktuellen thread auf.



  • wie oben schon gefragt: wofür möchtest du denn weniger als sleep(1) warten?



  • Ja, es würde mit Asm über NOP funktionieren. Steht für No Operation und macht halt nix 🙂



  • Vertex schrieb:

    Ja, es würde mit Asm über NOP funktionieren. Steht für No Operation und macht halt nix 🙂

    Genau und braucht (ich glaube) 2 Taktzyklen, das macht bei 500MHz länger als bei 2000MHz.
    Eine Taktzeitmessung muß in relation zur CPU Frequenz stehen, dazu stellt die API was bereit, welches ich bereits genannt habe.



  • MiC++ha schrieb:

    Vertex schrieb:

    Ja, es würde mit Asm über NOP funktionieren. Steht für No Operation und macht halt nix 🙂

    Genau und braucht (ich glaube) 2 Taktzyklen, das macht bei 500MHz länger als bei 2000MHz.
    Eine Taktzeitmessung muß in relation zur CPU Frequenz stehen, dazu stellt die API was bereit, welches ich bereits genannt habe.

    Besteht da nicht die Gefahr dass der Compiler die NOP´s wegoptimiert?

    MfG Spacelord



  • 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" wirst

    Es 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" wirst

    Windows 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.


Anmelden zum Antworten