Results 1 to 8 of 8

Thread: Timing issues

  1. #1
    bewildered NNTP User

    Default Timing issues

    I recently tried moving some existing software from 9.3 to 10.3 but this seems to cause some issues with timing.

    when running the code on 10.3 it seems to go through phases where timed events seem to take twice as long although most of the time it seems correct.

    The only thing I think of that might cause this is the change to a tickless kernel, but rebuilding the kernel with this disabled didn't seem to make any difference

    Any ideas of what could cause this?

    The program is written in c++ and uses setitimer and sigaction to run a funtion every microsecond

  2. #2
    Join Date
    Jul 2008
    Location
    NJ, USA
    Posts
    43

    Default Re: Timing issues

    Did you just "move" it or recompile it?
    J. Antman
    Dedicated SuSE user since October, 2001 (7.3)
    http://www.jasonantman.com
    http://blog.jasonantman.com

  3. #3
    bewildered NNTP User

    Default Re: Timing issues

    I did a full recompilation of the software.

    I have rebuilt on 10.2 and it seems to work fine on that, so it must be something that was introduced in 10.3


    It all starts up working properly, and if i am actively using the computer it is fine, but when I leave the programme running the clock seems to slow down after 5-10 minutes

  4. #4
    Join Date
    Jun 2008
    Location
    Oklahoma, US
    Posts
    822

    Default Re: Timing issues

    bewildered wrote:

    >
    > I did a full recompilation of the software.
    >
    > I have rebuilt on 10.2 and it seems to work fine on that, so it must be
    > something that was introduced in 10.3
    >
    >
    > It all starts up working properly, and if i am actively using the
    > computer it is fine, but when I leave the programme running the clock
    > seems to slow down after 5-10 minutes
    >
    >


    Sounds like cpu frequency scaling is contributing. As long as you're using
    the system, the cpu clock is kept high, when you leave it idle, the system
    saves energy by shifting the cpu to a lower, slower clock speed. If your
    program calibrates itself against the 'high speed' clock, it will be slow
    when running during the 'slow clock' periods.

    If you're running a function every *micro*second, goodness! 1,000,000 times
    a second? With system overhead and non-optimal interrupt routines, I would
    imagine that it gets skipped occasionally while in slow-clock.

    Just wondering... what on earth needs to be run each micro second? Wow.

    Consider: 2Ghz machine, 2,000,000,000 (approx) clock ticks a second. If
    you're running something 1,000,000 times a second, it (theoretically) only
    gets 2,000 ticks to get anything done before it gets called again. Many
    instructions take 2 or more clock ticks to perform... so you've got LESS
    than 1,000 instructions (probably more like 500-600 really) you can execute
    before your interrupt is called again.

    And that's only considering the cpu running your function alone. Not
    counting the overhead involved with watching the keyboard for your inputs,
    displaying things on the screen, handling network packets, etc.

    Wow.

    Interesting.
    --
    L R Nix
    lornix@lornix.com

  5. #5
    bewildered NNTP User

    Default Re: Timing issues

    The micro-second is from the struct timeval which I have just set to be the shortest possible interval to make it as accurate as possible. As the Linux kernel only 'ticks' at a maximum of 1000Hz (I had to recompile the kernel to enable this as the default changed from 9.x to 10.x) it will only be milli-seconds.


    I had assumed it was due to CPU frequency scaling, but as far as i am aware I have disabled all those options from the kernel and changed the power saving settings so it should not happen

  6. #6
    Join Date
    Jun 2008
    Location
    Oklahoma, US
    Posts
    822

    Default Re: Timing issues

    bewildered wrote:

    >
    > The micro-second is from the struct timeval which I have just set to be
    > the shortest possible interval to make it as accurate as possible. As
    > the Linux kernel only 'ticks' at a maximum of 1000Hz (I had to
    > recompile the kernel to enable this as the default changed from 9.x to
    > 10.x) it will only be milli-seconds.
    >
    >
    > I had assumed it was due to CPU frequency scaling, but as far as i am
    > aware I have disabled all those options from the kernel and changed the
    > power saving settings so it should not happen
    >
    >


    Oh, ok.

    Looking more at setitimer... are you using 'ITIMER_REAL', 'ITIMER_VIRTUAL',
    or 'ITIMER_PROF'? The man page tells that _REAL counts in real-time, while
    _VIRTUAL only counts when the process is running. That could be an issue,
    since a process could be bumped if higher priority items needed to be run.

    Also, if you don't handle the signal quickly enough, it may be dropped when
    another signal is generated from setitimer. Are you doing heavy work in
    the signal handler?



    --
    L R Nix
    lornix@lornix.com

  7. #7
    bewildered NNTP User

    Default Re: Timing issues

    the handler is set up as follows

    Code:
        // Set the timer to run continuously, producing a signal every 10ms
        timer_value.it_value.tv_sec = 0;
        timer_value.it_value.tv_usec = 1;
        timer_value.it_interval.tv_sec = 0;
        timer_value.it_interval.tv_usec = 1;
    
        // Store the process id of the rt transmit thread
        pid_t pid = getpid();
        Thread_Manager->Store_RT_Transmit_Process_ID( pid );
    
        action.sa_handler = Alarm_Signal_Wrapper;
        action.sa_flags = SA_NOMASK;
        sigemptyset(&action.sa_mask);
    
        sigaction( SIGALRM, &action, NULL);
    
        // Create the alarm timer to run every 10ms
        res = setitimer( ITIMER_REAL, &timer_value, NULL );
    and the process called has only a small amount of processing:

    Code:
    void CTransmitter::Alarm_Signal_Wrapper( int data )
    {
    
        static pthread_mutex_t runOnceMutex = PTHREAD_MUTEX_INITIALIZER;
    
        CTransmitter::instance()->Received_Signals++;
    
        if(pthread_mutex_trylock(&runOnceMutex) == 0)
        {
            CTransmitter::instance()->Alarm_Signal_Handler();
            pthread_mutex_unlock(&runOnceMutex);
        }
    
    }

    The alarm signal should always be processed, i will put some debug text in to try and determine if the thread is being locked out for any significant times

  8. #8
    Join Date
    Jun 2008
    Location
    Oklahoma, US
    Posts
    822

    Default Re: Timing issues

    bewildered wrote:

    >
    > the handler is set up as follows
    >
    >
    > Code:
    > --------------------
    > // Set the timer to run continuously, producing a signal every
    > 10ms
    > timer_value.it_value.tv_sec = 0;
    > timer_value.it_value.tv_usec = 1;
    > timer_value.it_interval.tv_sec = 0;
    > timer_value.it_interval.tv_usec = 1;
    >
    > // Store the process id of the rt transmit thread
    > pid_t pid = getpid();
    > Thread_Manager->Store_RT_Transmit_Process_ID( pid );
    >
    > action.sa_handler = Alarm_Signal_Wrapper;
    > action.sa_flags = SA_NOMASK;
    > sigemptyset(&action.sa_mask);
    >
    > sigaction( SIGALRM, &action, NULL);
    >
    > // Create the alarm timer to run every 10ms
    > res = setitimer( ITIMER_REAL, &timer_value, NULL );
    > --------------------
    >
    >
    > and the process called has only a small amount of processing:
    >
    >
    > Code:
    > --------------------
    > void CTransmitter::Alarm_Signal_Wrapper( int data )
    > {
    >
    > static pthread_mutex_t runOnceMutex = PTHREAD_MUTEX_INITIALIZER;
    >
    > CTransmitter::instance()->Received_Signals++;
    >
    > if(pthread_mutex_trylock(&runOnceMutex) == 0)
    > {
    > CTransmitter::instance()->Alarm_Signal_Handler();
    > pthread_mutex_unlock(&runOnceMutex);
    > }
    >
    > }
    > --------------------
    >
    >
    >
    > The alarm signal should always be processed, i will put some debug text
    > in to try and determine if the thread is being locked out for any
    > significant times
    >
    >


    Based on your code... you're asking for a signal every microsecond, not
    every 10 milliseconds.

    the lines near the top of your post where you have

    timer_value.it_value.tv_usec = 1;
    timer_value.it_interval.tv_usec = 1;

    Should be 10000 to give 10msec timing.

    The units are microseconds on those struct entries.

    --
    L R Nix
    lornix@lornix.com

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •