Hello Stanislaw, On Thu, Apr 2, 2009 at 5:41 PM, Stanislaw Gruszka <[email protected]>wrote:
> Hi. > > We found the periodic timers ITIMER_PROF and ITIMER_VIRT are unreliable, > they > have systematic timing error. For example period of 10000 us will not be > represented by the kernel as 10 ticks, but 11 (for HZ=1000). The reason is > that > the frequency of the hardware timer can only be chosen in discrete steps > and > the actual frequency is about 1000.152 Hz. So 10 ticks would take only > about > 9.9985 ms, the kernel decides it must never return earlier than requested, > so > it rounds the period up to 11 ticks. This results in a systematic > multiplicative > timing error of -10 %. The situation is even worse where application try to > request with 1 thick period. It will get the signal once per two kernel > ticks, > not on every tick. The systematic multiplicative timing error is -50 %. He > have > program [1] that shows itimers systematic error, results are below [2]. > > To fix situation we wrote two patches. First one just simplify code related > with itimers. Second is fix, it change intervals measurement resolutions > and > correct times when signal is generated. However this add some drawback, > that > I'm not sure if are acceptable: > > - the time between two consecutive tics can be smaller than requested > interval > > - intervals values which are returned to user by getitimer() are not > rounded up > > Second drawback mean that applications which first call setitimer() then > call getitimer() to see if interval was round up and to correct timings, > will potentially stop works. However this can be only problem with > requested > interval smaller than 1/HZ, as for intervals > 1/Hz we can generate signals > with proper resolution. > > Cheers > Stanislaw Gruszka > > [1] PROGRAM SHOWS ITIMERS SYSTEMATIC ERRORS > Thanks for this test program. We would like to test this on some of our kernels. However, i have a question. The % of errors you have shown pre and post patch. If i use this test as a functional verification test, how much % error can be considered as safe/pass ? And can your test be included inside LTP (http://ltp.sourceforge.net/) under GPL ? Regards-- Subrata > > > ============================================================================= > > /* > * Measures the systematic error of a periodic timer. > * Best run on an otherwise idle system, so that the simplifying assumption > * cpu_time_consumed_by_this_process==real_elapsed_time holds. > */ > > #include <sys/time.h> > #include <signal.h> > #include <stdio.h> > #include <stdlib.h> > > /* This is what profiling with gcc -pg uses: */ > #define SIGNAL SIGPROF > #define ITIMER ITIMER_PROF > > //#define SIGNAL SIGVTALRM > //#define ITIMER ITIMER_VIRTUAL > > //#define SIGNAL SIGALRM > //#define ITIMER ITIMER_REAL > > #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) > > const int test_periods_us[] = { > 10000, /* glibc's value for x86(_64) */ > 9998, /* this value would cause a much smaller error */ > 1000 /* and this is what is used for profiling on ia64 */ > }; > > volatile int prof_counter; > > void handler(int signr) > { > prof_counter++; > } > > void test_func(void) > { > int i = 0; > int count = 0; > > for(i=0; i<2000000000; i++) > count++; > } > > double timeval_diff(const struct timeval *start, const struct timeval *end) > { > return (end->tv_sec - start->tv_sec) + (end->tv_usec - > start->tv_usec)/1000000.0; > } > > void measure_itimer_error(int period_us) > { > struct sigaction act; > struct timeval start, end; > double real_time, counted_time; > > prof_counter = 0; > > /* setup a periodic timer */ > struct timeval period_tv = { > .tv_sec = 0, > .tv_usec = period_us > }; > struct itimerval timer = { > .it_interval = period_tv, > .it_value = period_tv > }; > act.sa_handler = handler; > sigemptyset(&act.sa_mask); > act.sa_flags = 0; > if (sigaction(SIGNAL, &act, NULL) < 0) { > printf("sigaction failed\n"); > exit(1); > } > if (setitimer(ITIMER, &timer, NULL) < 0) { > perror("setitimer"); > exit(1); > } > > /* run a busy loop and measure it */ > gettimeofday(&start, NULL); > test_func(); > gettimeofday(&end, NULL); > > /* disable the timer */ > timer.it_value.tv_usec = 0; > if (setitimer(ITIMER, &timer, NULL) < 0) { > perror("setitimer"); > exit(1); > } > > counted_time = prof_counter * period_us / 1000000.0; > real_time = timeval_diff(&start, &end); > printf("Requested a period of %d us and counted to %d, that should > be %.2f s\n", > period_us, prof_counter, counted_time); > printf("Meanwhile real time elapsed: %.2f s\n", real_time); > printf("The error was %.1f %%\n\n", (counted_time/real_time - > 1.0)*100.0); > } > > int main() > { > int i; > for (i=0; i<ARRAY_SIZE(test_periods_us); i++) > measure_itimer_error(test_periods_us[i]); > return 0; > } > > > =============================================================================== > > > [2] TEST PROGRAM RESULTS > > Test program results for unpatched kernel: > ========================================== > > Requested a period of 10000 us and counted to 644, that should be 6.44 s > Meanwhile real time elapsed: 7.10 s > The error was -9.2 % > > Requested a period of 9998 us and counted to 708, that should be 7.08 s > Meanwhile real time elapsed: 7.08 s > The error was -0.1 % > > Requested a period of 1000 us and counted to 3542, that should be 3.54 s > Meanwhile real time elapsed: 7.09 s > The error was -50.1 % > > To fix situation we wrote two patches, first just simplify code related > with itimers. Second > > Test program results after patches applied: > =========================================== > > Requested a period of 10000 us and counted to 708, that should be 7.08 s > Meanwhile real time elapsed: 7.10 s > The error was -0.2 % > > Requested a period of 9998 us and counted to 709, that should be 7.09 s > Meanwhile real time elapsed: 7.10 s > The error was -0.1 % > > Requested a period of 1000 us and counted to 7100, that should be 7.10 s > Meanwhile real time elapsed: 7.11 s > The error was -0.1 % > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to [email protected] > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > -- Regards & Thanks-- Subrata
------------------------------------------------------------------------------
_______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
