C++ While-Schleife nur alle 15ms ?

Fireball89

Captain
Registriert
Aug. 2007
Beiträge
3.498
Leute, ich glaub ich hab n Brett vorm Kopf.

Code:
#include "stdafx.h"
#include <Windows.h>
#include <iostream>


int _tmain(int argc, _TCHAR* argv[])
{
	ULONGLONG time1;
	ULONGLONG time2;
	time1=GetTickCount64();
	while (1) {
		time2=GetTickCount64();
		if (time2-time1>0) {
			std::cout << time2-time1 << "\n";
			time1=time2;
		}
	}
	return 0;
}

Wie kann es sein, dass da immer nur 15 oder 16 rauskommt?!?
Irgendwann müsste time2-time1 doch mal 1 sein, oder?
Lasse ich die Bedingung im if-Statement weg, dann kommt immer nur 0.

//edit: Sry, ich bin so doof. Hat sich schon erledigt. Lesen hilft ... GetTickCount64 hat nur ne Auflösung von 10-16 ms. 2 Std. Ärger und jetzt merk ichs.
 
Zuletzt bearbeitet:
AW: While-Schleife nur alle 15ms ?!?

nimm QueryPerformanceCounter() / QueryPerformanceFrequency()
 
Zuletzt bearbeitet:
Würde mich wundern, wenn sich die Features irgendwie Zeitinformationen hergreifen können die feiner
sind als die, die das Betriebssystem bereitstellt. Aber ich lasse mich gern eines besseren belehren.
 
asdfman schrieb:
Würde mich wundern, wenn sich die Features irgendwie Zeitinformationen hergreifen können die feiner
sind als die, die das Betriebssystem bereitstellt. Aber ich lasse mich gern eines besseren belehren.

Das stimmt natürlich. std::chrono bietet zwar prinzipiell die Typen und Funktionen zum ermitteln von Zeiten mit Mikrosekundengranularität, aber ob die dann tatsächlich auch mikrosekundengranular sind, hängt natürlich davon ab, ob es das Betriebssystem hergibt.
 
Es gibt ja versch. Uhren: system_clock wäre die normale Windowsuhr. Wenn man high_resolution_clock nimmt, wird die genaueste nutzbare Uhr genommen. Ob der Compilerbauer selber eine konstruiert oder im Hintergrund auf QueryPerformanceCounter() zugreift kann dem Programmierer egal sein.

Und wenn der Standard einem einfach die genaueste verfügbare Uhr an die Hand gibt, dann ist das sehr praktisch und immer noch systemunabhängig, also die wohl empfehlenswerte Lösung. ;)

Sollte VC11 einfach nur auf QueryPerformanceCounter zugreift, dann liegt er im Mikrosekundenbereich. Wollte damit nur das I-Tüpfelchen darstellen.
 
Zuletzt bearbeitet:
Ist ja auch der empfehlenswerteste Ansatz. Wollte nur geklärt haben, daß letzten Endes natürlich doch das OS die nötige Funktionalität liefern muß, weil zaubern kann C++11 leider noch nicht (vielleicht klappt das mit dem nächsten Standard .... using std::magic; ;)).
 
Die QueryPerformanceCounter Sachen sind dazu da, um Zeitintervalle zu messen - nicht um in regelmäßigen Abständen etwas auszuführen. Und ein Busy-Wait ist genauso wenig geeignet - verfälscht eher die Ergebnisse, weil das System in Überlast gerät.

Hier gibt's ein hübsches Tutorial:
http://www.codeproject.com/Articles/1236/Timers-Tutorial

Interessant dürften die Queue Timers sein. Aber vorsicht, die Callbacks finden in einem extra Thread statt. Wenn ein Thread länger als das Zeitintervall braucht, kommt ggf. ein zweiter Thread parallel dazu. Immer schön sauber mit WaitForSingleObject im main-Thread warten und nicht auf gemeinsamen Variablen/Objekten (cout gehört auch dazu) rummanschen (und auch garnicht erst mit Mutexes anfangen, das geht nur in die Hose).

Einfacher als QueueTimers sind die WaitableTimers, ebenfalls in dem Tutorial beschrieben und haben das Thread-Problem nicht, sind dafür aber weniger flexibel. Wichtig ist nur, dass der Thread, der den TimerCallback bekommt, gerade eine Funktion aufgerufen hat, die ihn alterable macht, also SleepEx, WaitForSingleObject, WaitForMultipleObjects, .... Damit legt er sich schlafen, verbraucht keine Rechenzeit und der Aufruf kehrt zurück, sobald der Timer getriggert wurde. Steht auch alles im Tutorial.
 
Zurück
Oben