[C++/ASM] Prozessor Ticks

[Moepi]1

Lt. Commander
Registriert
Jan. 2002
Beiträge
1.233
Hallo,
ich muss möglichst exakt die Laufzeit von einem Programm messen. Die time.h ist viel zu ungenau und da das ganze eh unter nem Minimallinux laufen wird, um sinnvolle Ergebnisse zur bringen, bin ich auf die Idee gekommen, die Prozessor Ticks seit dem letzten Reset auszulesen. Die Funktion RDTSC erledigt das. Allerdings ist es ein 64bit Unsignend Integer - und sowas gibts in C wieder nicht. Folgendes Programmschnippsel:

Code:
unsigned long rdtsc()
{
	__asm( ".intel_syntax noprefix\n"
		"pusha\n"
		"rdtsc\n"
		"mov _tlow, eax\n"
		"mov _thigh, edx\n"
		"popa\n"
	);

	
	unsigned long ticks = 0;
	ticks ^= thigh;
	ticks = ticks << 32;
	ticks ^= tlow;
	
	return ticks;
}
Das ganze wird vor und nach dem Ausführen der Benchmarkfunktion ausgeführt und sollte entsprechend die Ticks zurückgeben, die ich dann durch die Prozessorfrequenz teilen kann, um ms zu bekommen. Problem ist jetzt, dass der Unsigned Integer nur 32bit lang ist und damit natürlich das verschieben um 32 Stellen nach links, um die beiden Register EAX und EDX zu kombinieren, in die Hose geht.

Meine Frage daher: wie schaffe ich es in C++, einen Ganzzahlwert aus zwei 32bit Integers zu basteln und mit dem zu rechnen?


Danke schon mal & gn8!


PS: tlow und tihigh sind globale Variablen vom Typ "unsigned int"
 
Auf Anhieb fallen mir da verschiedene Möglichkeiten ein.

- Verwende einen 64 Bit Compiler, auf einer 64 Bit CPU. Das ist heutzutage ja möglich.

- Unter .NET Framework gibt es Konvertierungsroutinen (z.B. Convert.ToUInt64-Methode)
eventuell gibt es auch noch andere Klassen die so etwas bieten.

- Behandle die beiden 32 Bit Werte getrennt. Bei einer Division durch 2 lässt sich das ganze ja relativ einfach auf Shiftoperationen abbilden. Die kann man auch getrennt auf 2 32 Bit Werten durchführen.

MfG

Arnd
 
die ticks danach - ticks davor ergeben mit sicherheit wieder 32 bit bereich.
behalte die 4 * 32 bit werte und schreibe ne substraktionsfunktion.
das ergerbnis deiner funktion wäre somit ein struct type mit 2*unsigned long

falls doch zu hoch kannste die werte doch immer noch in ext double skalieren, dann abziehen und dann durch mhz teilen...
funktionsergebnis extend double statt unsigned long
 
Viele Compiler bieten einen unsigned long long Datentyp an, auch wenn der nicht standardkonform ist. Dieser ist meist 64 Bit groß. Kannst du notfalls mit sizeof prüfen.


FYI:
Sofern Du ein Multiprozessor / Hyperthreading-System hast, kannst du mit den Ticks alleine nichts anfangen.
 
Zurück
Oben