PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Windows CE] Möglichst genaue Zeitmessung für C++ gesucht


Senior Sanchez
2005-11-27, 19:11:50
Hallo,

Ich bin gerade ein bissl am rumprobieren mit VS2005 (habe damit vorher noch nie gearbeitet, es erschlägt einen da fast, aber es ist einfach mal hammergeil :biggrin: ) und habe da nen kleines Problemchen *g*

Ich hatte neulich mal testweise nen kleines Primzahlprogramm geschrieben (dazu die frage nach der Java VM/Compiler und was aus a+=b wird) und es nun erst nach C++ für x86 portiert und jetzt auch für die StrongARM/XScale Architektur.

Unter Java ist Zeitmessung ja sehr easy, aber unter C++ doch haariger, wie ich finde.
Beim Port für x86 konnte ich, da ich dort Zugriff auf verschiedene Header habe (sys/timeb.h und time.h), die Zeit zumindest in ms messen.
Nur diese Header finden sich nicht bei Windows CE, somit kann ich auch mein Programm damit nicht kompilieren.
Kennt da jemand jetzt ne Lösung um unter Windows CE die Zeit möglichst genau messen zu können?

Demirug
2005-11-27, 19:16:19
Schau mal unter QueryPerformanceCounter und QueryPerformanceFrequency in der Hilfe nach. Diese beiden Funktionen sind die CPU unabhängige Methode zur Zeitmessung unter Windows.

Trap
2005-11-27, 19:17:52
Die CPU hat ein TSC-Register, die einfachste Lösung wäre mit inline asm den Inhalt in irgendeine Variable kopieren

Senior Sanchez
2005-11-27, 19:42:29
Schau mal unter QueryPerformanceCounter und QueryPerformanceFrequency in der Hilfe nach. Diese beiden Funktionen sind die CPU unabhängige Methode zur Zeitmessung unter Windows.

Hmm, das wirkt interessant und die Deklaration und so weiter, klappt auch ohne Probleme, aber dann beim ausrechnen hapert es.

Dort wird der definierte Typ (eine union) LARGE_INTEGER benutzt und ich habe keinen Plan, wie ich nun einfache arithmetische Operationen (Subtraktion, Division) darauf anwenden kann. Kannste mir da weiterhelfen?


@trap
Danke für diesen Hinweis, aber soweit bin ich noch nicht in die Tiefen der ARM-Architektur runtergestiegen *g* (ich kratze gerade anner Oberfläche ;) ).
Was ist ein TSC-Register? Hat ja denke ich auf jedenfall was mit Zeit zu tun.

Trap
2005-11-27, 19:51:41
Wenn QueryPerformanceCounter geht sollte man natürlich das benutzen.

Das TSC-Register ist ein Register dass jeden Takt um 1 erhöht wird (TSC=timestamp counter). Läuft also alle paar Sekunden über, ist aber sehr genau. QueryPerformanceCounter benutzt die Werte davon, zählt aber mit genug Bits weiter so dass es nach einem Überlauf noch richtig weiterzählt.

Ich hab bis jetzt die LARGE_INTEGER in unsigend long long gecastet und damit gerechnet, vielleicht gibt es auch eine besser Möglichkeit, hab nicht lang gesucht.

Coda
2005-11-27, 20:05:35
Ich würde nen Bogen um den TSC machen, vor allem weil die ganzen mobilen Chips auch Stromsparfunktionen und dadurch Taktschwankungen haben. Besser QueryPerformanceCounter...

Senior Sanchez
2005-11-27, 21:43:27
Ich hab bis jetzt die LARGE_INTEGER in unsigend long long gecastet und damit gerechnet, vielleicht gibt es auch eine besser Möglichkeit, hab nicht lang gesucht.

start, end und freq sind jeweils pointer auf LARGE_INTEGER Variablen.

unsigned long long anfang = *start;
unsigned long long ende = *end;
unsigned long long frequenz = *freq;

Das klappt bei mir irgendwie nicht, er sagt immer dass er nicht von LARGE_INTEGER auf __int64 konvertieren kann.

Trap
2005-11-27, 21:55:45
Ich hab es bis jetzt so benutzt:
unsigned long long before;
QueryPerformanceCounter((LARGE_INTEGER*)&before);

Senior Sanchez
2005-11-27, 22:08:05
Ich hab es bis jetzt so benutzt:
unsigned long long before;
QueryPerformanceCounter((LARGE_INTEGER*)&before);

yo, genau so ist es auch, und so gehts auch, hatte es vorhin gefunden, aber trotzdem danke :)

Mal ne Frage, welches ist denn der genaueste Gleitkommatyp?

Trap
2005-11-27, 22:14:11
float<=double<=long double

long double ist immer der genauste Typ, bei MS-Compilern unter Win32 allerdings identisch mit double.

Senior Sanchez
2005-11-27, 22:20:15
float<=double<=long double

long double ist immer der genauste Typ, bei MS-Compilern unter Win32 allerdings identisch mit double.

Hmm, scheinbar trotzdem zu klein.
Ich wollte jetzt die zeitdauer ausrechnen ( (ende - start) / counts pro sekunde), allerdings scheints irgendwie net zu klappen. Ich denke mal das liegt anner ganzzahldivision? Wie würde der Aufruf denn aussehen, wenn ich ne Fließkommazahl haben möchte? Ich hab gerade irgendwie nen Brett vorm kopf.

Coda
2005-11-28, 00:11:21
Du must bevor du dividierst in FP umwandeln.

Senior Sanchez
2005-11-28, 00:24:39
Du must bevor du dividierst in FP umwandeln.

Das habe ich mir auch gedacht und deshalb gedacht dass ein * 1.0 reicht. Oder muss ich explizit * 1.0d bzw. * 1.0f schreiben?

Coda
2005-11-28, 01:53:02
((double)(ende - start) / (double)cycles)