Skip to content

The default frequency is misleading #163

Open

Description

@antocuni

TL;DR; version: vmprof should run at 1000Hz, but it runs at 250Hz.

By default, vmprof uses a DEFAULT_PERIOD = 0.00099, which is almost 1000Hz.
However, on all machines on which I tried linux seems to deliver SIGPROF at max 250Hz, so you get many less samples than what you would expect.
But, if you use real_time=True, then it uses SIGALRM which seems to support higher frequency.

I think this is related to the CONFIG_HZ_* kernel settings; on my machine (ubuntu 16.10, kernel 4.8.0) I have:

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

You can easily see it by running this example, stolen from here. On my machine, I get "4016 Hz or higher" with SIGALRM, and "250 Hz" with SIGPROF.

#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);
    sigaction (SIGPROF, &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);
    setitimer (ITIMER_PROF, &timer, NULL);
    while (1);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions