Linux timer interrupt frequency is an important parameter for near to real-time and multimedia applications running on Linux. The timer interrupt frequency directly impacts the capability of any near-to real time and multimedia application to process events at high frequencies. The term high in this context means usually greater than 100 Hz (10 ms).

In the old days the kernel configuration setting CONFIG_HZ was the most important setting for the kernel timer frequency. It was defined at compilation time of the kernel and settings varied between distributions and kernel versions.

Today, a number of other kernel settings - such as NO_HZ, HIGH_RES_TIMERS - impact the kernel timer interrupt frequency as well. Finally the availability of High Precision Event Timer (HPET) support is also an important feature.

All these settings may be retrieved easily from the current kernel configuration. For example:

$ cat /boot/config-`uname -r` | grep HZ
# CONFIG_HZ_1000 is not set
# CONFIG_HZ_300 is not set
CONFIG_MACHZ_WDT=m
CONFIG_NO_HZ=y
CONFIG_HZ=100
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set

$ cat /boot/config-`uname -r` | grep HIGH_RES_TIMERS
CONFIG_HIGH_RES_TIMERS=y

However, for a near to real-time or multimedia application the effective achievable timer interrupt frequency counts. This frequency can be estimated quite well with timer interrupts. The small example program below depicts an algorithm to determine the actual achievable timer interrupt frequency using by actually requesting timer interrupts at high frequencies.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>

#define USECREQ 250
#define LOOPS 1000

void event_handler(int signum)
{
    static unsigned long cnt = 0;
    static struct timeval tsFirst;
    if (cnt == 0)
    {
        gettimeofday(&tsFirst, 0);
    }
    cnt++;
    if (cnt >= LOOPS)
    {
        struct timeval tsNow;
        struct timeval diff;
        setitimer(ITIMER_REAL, NULL, NULL);
        gettimeofday(&tsNow, 0);
        timersub(&tsNow, &tsFirst, &diff);
        unsigned long long udiff = (diff.tv_sec * 1000000) + diff.tv_usec;
        double delta = (double)(udiff / cnt) / 1000000;
        int hz = (unsigned)(1.0 / delta);
        printf("kernel timer interrupt frequency is approx. %d Hz", hz);
        if (hz >= (int)(1.0 / ((double)(USECREQ) / 1000000)))
        {
            printf(" or higher");
        }
        printf("\n");
        exit(0);
    }
}

int main(int argc, char **argv)
{
    struct sigaction sa;
    struct itimerval timer;

    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = &event_handler;
    sigaction(SIGALRM, &sa, NULL);
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = USECREQ;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = USECREQ;
    setitimer(ITIMER_REAL, &timer, NULL);
    while (1) ;
}

To check your particular system regarding time interrupt frequency capabilities please follow the instructions below create a local copy of this small program, as e.g. frequency-test.c. Issue is that this setting has an important impact on near to real-time applications.

  • Create a local copy of this small program, as e.g. frequency-test.c
  • Compile it with gcc: "gcc frequency-test.c"
  • Run it: "./a.out"

On a Ubuntu 8.04 LTS server (Hardy) ge get:

$ ./a.out 
kernel timer interrupt frequency is approx. 4016 Hz or higher

On a Ubuntu 10.04 LTS server (Lucid) ge get:

$ ./a.out 
kernel timer interrupt frequency is approx. 4016 Hz or higher

On a little bit older OpenSUSE with kernel 2.6.22.5-31-bigsmp we get:

$ ./a.out 
kernel timer interrupt frequency is approx. 249 Hz

Both systems are multicore server chassis.

If the timer interrupt frequency determined on your system is for example around 250Hz, it will be very difficult for any near to real-time or multimedia application to send out an isochronous data stream of 250 packets per second (pps).