Noch kürzer Warten als Sleep(1)



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



  • naja, du könntest das mit asm machen ... ich weiß net, wies auf x86 cpu is, aber auf den guten alten mcs51 gibts da nen befehl für, einfach einen systemtakt lang nichts zu tun.... und dann musste dir halt ausrechnen, wie viele systemtakte deine cpu in deinem gewünschten zeitabschnitt machen.
    bei zB 12 mHz war glaub ich ein sytemtakt genau eine µs.



  • Habe mal einen Befehl ähnlich Sleep gebraucht, dem man mikrosekunden angeben konnte. Frag mich bloss nicht, wie der heisst, sorry!

    - Adrian



  • Mit
    QueryPerformanceCounter
    in verbindung mit
    QueryPerformanceFrequency

    geht das



  • 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


Anmelden zum Antworten