Patrick Schaaf in dcoup, 16. Dez. 2002
>Ich fürchte, ohne Kernel Patch überhaupt nicht! Der Linux Kernel arbeitet
>mit einem auf 1/100 Sekunde eingestellten Timer, und genauer können die
>davon abgeleiteten Funktionen nicht arbeiten.
Das ist falsch. x86-Linux bietet mit dem gettimeofday()-syscall schon
seit Ewigkeiten eine Zeit, die deutlich besser aufloest als 100Hz.
Der 100Hz-Timer-Interrupt wird traditionell von einem irgendwo im
Chipset sitzenden Timer angestossen, der mit einer Frequenz irgendwo
ueber 1Mhz laeuft. Der Prozessor kann (natuerlich mit Kernel-Privilegien)
jederzeit ueber einen INB den aktuellen "Laufstand" dieses Timers
abfragen, und gettimeofday() nutzt das - wie erwaehnt schon lange - um die
Zeit im unter-Millisekunden-Bereich zu ermitteln.
Sind die von Dir erwaehnten Zyklenzaehler verfuegbar, was der Kern beim
Booten merkt, dann verwendet gettimeofday sie auch, um die Praezision
noch weiter zu steigern.
>Der P3 besitzt zwar ein
>Taktzyklenzähler (der sich hierfür durchaus eignen täte) leider ist der zum
>Lesen nötige Befehl einer aus der Klasse "priviligiert" d. h. dem Kernel
>vorenthalten.
Das ist falsch. RDTSC, wie diese Instruktion heisst, ist unprivilegiert.
Ich nutze sie gelegentlich, um kurze Codefragmente im Userlevel auszumessen.
Du kannst die entsprechende Inline-Assembler-Funktion einfach aus den
Kernel-Includes extrahieren und verwenden. Siehe unten.
Gruss
Patrick
static inline unsigned long long read_tsc(void)
{
unsigned long high, low;
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
return ((unsigned long long)high << 32) | low;
}
int main(int argc, char **argv)
{
printf("%Lu\n", read_tsc());
printf("%Lu\n", read_tsc());
return 0;
}
Noch ein paar Hinweise dazu (hoffe man verzeiht mir, das ist eigentlich
nix Unix-spezifisches :)
Ich habe gerade gesehen (/usr/src/linux/include/asm/msr.h), dass es ja
doch eine Spielart gibt, die gleich einen long long zurueckliefert.
Mein static-inline-wrapper duerfte also ueberfluessig kompliziert sein.
__asm__ __volatile__ ("rdtsc" : "=A" (val));
Ausserdem sollte man wissen, dass auf Prozessoren, die rdtsc nicht
unterstuetzen, an der Stelle Bekanntschaft mit Signalen gemacht wird.
Ich meine, das trifft alles kleiner als Pentium-MMX. Unter Linux
muesste man die Unterstuetzung mit "grep tsc /proc/cpuinfo" testen
koennen.
Ich wuerde das niemals in Produktionscode einsetzen.
Was gab's noch? Ach ja, auf SMP-Systemen kann rdtsc unsynchronisiert sein;
ohne Festzurren auf eine CPU kann ein Benchmark-Programm, dass auf rdtsc
aufbaut, grosse Spruenge machen. Fatal: auf den ueblichen 2-Prozessor
x86-Servern von Intel merkt man davon nichts... Aehnlich schoen sollen
Prozessoren sein, vor allem im Mobilbereich, die sich je nach Laune
hoch und runtertakten. Dann wird alles sehr relativ.
Bitte dieses Posting als Kommentar ueber die Funktion in deinem lib pasten.
Mache ich jetzt auch. |