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