Billige Uhr und Uhrenvergleiche
Die Abfrage eines TSC, als high resolution Timer bezeichnet (HR) kostet nichts, aber der Nachteil ist, dass sich die Taktrate des Prozessors ändern kann
Daher ist die Idee, daß hin- und wieder eine teurere gettimeofday(2)-Abfrage unsere billige Uhr kalibriert.
Es gibt zwei Gründe für die Interpolation aus zwei Punkten
Lineare Interpolation durch zwei Punkte (x1,y1) und (x2,y2) ergibt:
Y=(X-x2)*(y2-y1)/(x2-x1)+y2
Wir benötigen zwei Meßpunkte von der Systemuhr TSys gettimeofday(2)
und zwei zugehörige von dem HR. (thr)
Mit thr=X und tsys=Y ergibt sich also:
T=(Thr-thr2)*(tsys2-tsys1)/(thr2-thr1)+tsys2
Bei einem neuen Eingang einer Systemzeit passen wir unsere Stützstellen an.
Def. Korrelationsfaktor correlationfactor = (tsys2-tsys1)/(thr2-thr1)
Dieses funktioniert durchaus mit double-Rechnungen, allerdings ist die Nutzung der Floatingpoint-Arithmetik zu teuer.
Da thr2-thr1 > tsys2-tsys1 , behelfen wir uns mit dem
Def. Inversen Korrelationsfaktor invcorrelationfactor := (thr2-thr1)/(tsys2-tsys1)
Damit ergibt sich die Formel zu: T=(Thr-thr2)/invcorrelationfactor + tsys2.
Leider zeigt der Versuch, dass es einen Fehler bis zu 1ms gibt - das ist nicht akzeptabel. Offensichtlich schneidet die Division im inversen Korrelationsfaktor uns zu viele Stellen ab.
Um mehr Stellen zu erhalten, multiplizieren wir den Nenner mit 1024 (<<10), und korrigieren im Zähler das wieder, so
T=((Thr-thr2)<<10)/invcorrelationfactor+tsys2,Der Test zeigt ein befriedigtes Ergebnis.
clocktest [intervalllänge in s| random]
Nach jedem Intervall wird die Zeit verglichen.
Bei Random sind die Intervalle 500+EXPonentialverteilt gewählt, um eine
unreglmässige Kalibrierung zu simulieren.
Kosten gettimeofday = 1572 Kosten timesample = 714 kosten cheapclock = 383
d.h. Faktor 4 ist die Uhr billiger als die gettimeofday(2)
Der Fehler tritt in der letzen Stelle der us-Darstellung auf und scheint unabhängig von der Intervalllänge.
die Operationen von cheapclock auf:100*gettimeofday 7650 ticks 1*getimeofday 76.5 ticks 100*cheap.gettime 21842 ticks 1*cheap.gettime 218.42 ticks 100*cheap.timesample 15646 ticks 1*cheap.timesample 156.46 ticks
Offensichlich ist hier die "CheapClock" teuer wie der gettimeofday-Systemaufruf !
Diese Anormalie erklärt sich durch die VSyscalls, die keinen richtigen Wechsel in den Kern vornehmen.
(freundliche externe Messung vergleichbar mit clockvergleich):
Kosten gettimeofday = 74 ticks Kosten timesample = 368 ticks kosten cheapclock = 145 ticks
Kosten gettimeofday = 6664 ticks Kosten timesample = 45072 ticks kosten cheapclock = 4616 ticks
hier nur einen Faktor von 1.4. - vermutlich wird zuviel 64 bit-Arithmetik verwendet.
interessanterweise sind auch die Unterschiede bis ca. 15us und grösser als beim x86_64
clockvergleich sagt:
100*gettimeofday 212792 ticks 1*getimeofday 2127.92 ticks 100*cheap.gettime 79744 ticks 1*cheap.gettime 797.44 ticks 100*cheap.timesample 80704 ticks 1*cheap.timesample 807.04 ticks
hier ergibt sich ein Speedupfaktor von 2.6
(freundliche externe Messung vergleichbar mit clockvergleich):
Kosten gettimeofday = 1092 ticks Kosten timesample = 45936 ticks kosten cheapclock = 651 ticks
Speedupfaktor von etwa 1.7