Just how important is a monotonic clock? (18 Mar 2005)
In discussions with Zooko I did a little test to see how important the addition of CLOCK_MONOTONIC is really.
The alternative to using CLOCK_MONOTONIC is to have an itimer which increments a global, volatile counter at some number of Hz. You can do that with something like the following:
struct itimerval itv; memset(&itv, 0, sizeof(itv)); itv.it_interval.tv_sec = 1; itv.it_value.tv_sec = 1; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigalrm_handler; sigaction(SIGALRM, &sa, NULL); setitimer(ITIMER_REAL, &itv, NULL);
So I setup a test which tracks the difference between the true time elapsed (from CLOCK_MONOTONIC) and the count of global timer value. Firstly at 10Hz:
Nsecs elapsed | Global Tick Count | Skew in global count |
---|---|---|
3029049000 | 30 | 0 |
6061401000 | 60 | 0 |
9090753000 | 90 | 0 |
12120089000 | 120 | 1 |
15149773000 | 150 | 1 |
18178802000 | 180 | 1 |
21211143000 | 210 | 2 |
24240480000 | 240 | 2 |
27269822000 | 270 | 2 |
30299166000 | 300 | 2 |
33328513000 | 330 | 3 |
36357867000 | 360 | 3 |
39389203000 | 390 | 3 |
42418558000 | 420 | 4 |
45447899000 | 450 | 4 |
48477242000 | 480 | 4 |
51506593000 | 510 | 5 |
54537964000 | 540 | 5 |
57567285000 | 570 | 5 |
60596633000 | 600 | 5 |
63625987000 | 630 | 6 |
66655324000 | 660 | 6 |
69686677000 | 690 | 6 |
72716018000 | 720 | 7 |
75745363000 | 750 | 7 |
78774714000 | 780 | 7 |
81804702000 | 810 | 8 |
84854641000 | 840 | 8 |
87864766000 | 870 | 8 |
90894098000 | 900 | 8 |
93923444000 | 930 | 9 |
96952794000 | 960 | 9 |
99985163000 | 990 | 9 |
103014486000 | 1020 | 10 |
So, after 100 seconds the counter is already one second off. That's pretty terrible. Trying it again at 1Hz gives better results. I'm not going to give the whole table here but the skew is about 1 second lost every 20 minutes. Still not great.