Messages in this thread | | | Subject | [FYI] 2.6.13-rt3 and a nanosleep jitter test. | From | Steven Rostedt <> | Date | Wed, 31 Aug 2005 11:01:54 -0400 |
| |
Thomas,
I just was wondering how the HR Timers were in the latest -rtX patch and wrote my own little jitter test using nanosleep. Here's the results:
On vanilla 2.6.13-rc7-git1 (Yes I need to get over to 2.6.13)
# ./jitter starting calibrate finished calibrate: 2133.9060MHz 2133906034 time slept: 0.010000000 sec: 0 nsec: 10000000 max: 0.011997701 min: 0.011890522 avg: 0.011993485 greatest time over: 1997.701 usecs never ran under (good!) average time over: 1993.485 usecs
On 2.6.13-rt3:
# ./jitter starting calibrate finished calibrate: 2133.2960MHz 2133295991 time slept: 0.010000000 sec: 0 nsec: 10000000 max: 0.010034857 min: 0.010006309 avg: 0.010009213 greatest time over: 34.857 usecs never ran under (good!) average time over: 9.213 usecs
Not bad. I then ran a clean kernel compile as root with a -j3 (this is an 2x SMP machine), and tried the test again.
# ./jitter starting calibrate finished calibrate: 2133.3005MHz 2133300491 time slept: 0.010000000 sec: 0 nsec: 10000000 max: 0.010044836 min: 0.010014244 avg: 0.010030741 greatest time over: 44.836 usecs never ran under (good!) average time over: 30.741 usecs
Since the ticks per second is also calculated here, I ran it again using the calibration of the first run (still running that make):
./jitter -c 2133295991 passed in calibrate: 2133.2960MHz 2133295991 time slept: 0.010000000 sec: 0 nsec: 10000000 max: 0.010051293 min: 0.010012155 avg: 0.010030237 greatest time over: 51.293 usecs never ran under (good!) average time over: 30.237 usecs
And once more using the calibration found by 2.6.13-rc7-git1 (still running that make):
# ./jitter -c 2133906034 passed in calibrate: 2133.9060MHz 2133906034 time slept: 0.010000000 sec: 0 nsec: 10000000 max: 0.010058339 min: 0.010016418 avg: 0.010025571 greatest time over: 58.339 usecs never ran under (good!) average time over: 25.571 usecs
Some info on my machine:
$ cat /proc/cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 6 model : 10 model name : AMD Athlon(tm) MP 2800+ stepping : 0 cpu MHz : 2133.286 cache size : 512 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 1 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse syscall mp mmxext 3dnowext 3dnow bogomips : 4259.84
processor : 1 vendor_id : AuthenticAMD cpu family : 6 model : 10 model name : AMD Athlon(tm) Processor stepping : 0 cpu MHz : 2133.286 cache size : 512 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 1 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse syscall mp mmxext 3dnowext 3dnow bogomips : 4259.84
And attached is the jitter.c test. Must be run as root since it ups the priority to the max.
Have fun,
-- Steve
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <getopt.h> #include <sched.h> #include <unistd.h>
#define rdtsc(low,high) \ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
#define rdtscl(low) \ __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
#define rdtscll(val) \ __asm__ __volatile__("rdtsc" : "=A" (val))
#define LOOPS 100.0
int main(int argc, char **argv) { int c; unsigned long long start, end, tps = 0; double cal; double max=0,min=0,avg=0; int i; pid_t pid; struct sched_param sp; double sleeptime; unsigned long sec,nsec;
sleeptime = 0.01; sec = sleeptime; nsec = (sleeptime-sec) * 1000000000; pid = getpid();
memset(&sp,0,sizeof(sp)); sp.sched_priority = sched_get_priority_max(SCHED_FIFO); sched_setscheduler(pid,SCHED_FIFO,&sp);
while ((c=getopt(argc,argv,"c:")) != -1) { switch (c) { case 'c': tps = strtoll(optarg,NULL,10); break; default: exit(0); } }
if (!tps) { printf("starting calibrate\n"); rdtscll(start); sleep(8); rdtscll(end);
tps = end - start; tps >>= 3; printf("finished calibrate: "); } else { printf("passed in calibrate: "); } cal = tps; cal /= 1000000.0;
printf("%.4fMHz %llu\n",cal,tps);
for (i=0; i < LOOPS; i++) { struct timespec req = { sec, nsec }; unsigned long long t; rdtscll(start); nanosleep(&req,NULL); rdtscll(end); t = end - start; cal = t; cal /= (double)tps; if (!i || cal > max) max = cal; if (!i || cal < min) min = cal; avg += cal; }
avg /= LOOPS; printf("time slept: %.9f sec: %lu nsec: %lu\n",sleeptime,sec,nsec); printf("max: %.9f\n",max); printf("min: %.9f\n",min); printf("avg: %.9f\n",avg);
printf("greatest time over: %.3f usecs\n",(max-sleeptime)*1000000.0); if (min > sleeptime) { printf("never ran under (good!)\n"); } else { printf("Ran under!!! (by %.9f) nsecs\n",sleeptime-min); }
if (avg > sleeptime) printf("average time over: %.3f usecs\n",(avg-sleeptime)*1000000.0); else printf("average time ran under???\n"); exit(0); }
| |