EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: epicsTimer and rounding
From: "Hill, Jeff" <[email protected]>
To: Ralph Lange <[email protected]>, EPICS Core Talk <[email protected]>
Cc: Dirk Zimoch <[email protected]>
Date: Wed, 6 Jun 2012 16:15:55 +0000
Hi Ralph,

I made that tweak (subtracting one half of the quantum from the timer expiration time) when running the tests and attempting to optimize measured timer expiration as close as possible to the specified expiration time (on average). 

It occurred to me that the timer delay always starts somewhere midway between OS ticks. The presumption is that if we ask for a sleep of N quantums we will typically get an actual  sleep of somewhere between N and N+1 quantums. The sleep must be rounded up by a sane OS implementation to at least more or the same quantums than the user asked for in floating point (this was also your assumption as I recall in your email).

Statistics tells us that if the distribution of the random timer start time is independent of the OS tick time (we can't be certain of that actually but experimental evidence seems to support this assumption), then if we subtract off one half of a quantum from the delay we will get just what we want on average. This isn't what we want if we are just sleeping for awhile, but maybe it is what we want when optimizing the time precision of the timer queue. More on this later.

Related to this issue is of course what goes on in epicsThreadSleep. Note that, at least the windows version (see attached code at the end of the email), does make certain of two things. Presumably similar code exists for each of the OS specific implementations.

1) a sleep requested, less than one quantum, will be rounded up to one quantum (the OS also probably makes this check)
2) rounding occurs from the specified floating point seconds to the nearest number of quantums by adding .5 to the floating point number of quantums just before integer truncation.

In your email you were worried that a sleep close to the quantum will be off by 100% because of the one half quantum subtraction, but I believe that all OS specific implementations force a sleep of less than a quantum to be actually one quantum.

So Ralph makes the point that if the user ask for delay fff.fff then there should never be a timer expiration occurring that is less than a delay of fff.fff. So this is the crux of the matter isn't it; should we make the timer expiration delay as close as possible to the user's request on average (that's good for time algorithmic code such as a pid) or should we guarantee timer expiration delay is never less than the delay specified (maybe because we are concerned about cpu use with very short timer delays but see the previous paragraph).

Note also that overhead preparing to make the callback, for example taking and releasing a mutex, results in some additional precision disrupting delays unrelated to quantum.

If we make a change then of course the regression test should be run to characterize the new behavior in terms of the final measured delays when calling user callbacks. 

epicsShareFunc void epicsShareAPI epicsThreadSleep ( double seconds )
{
    static const unsigned mSecPerSec = 1000;
    DWORD milliSecDelay;

    if ( seconds <= 0.0 ) {
        milliSecDelay = 0u;
    }
    else if ( seconds >= INFINITE / mSecPerSec ) {
        milliSecDelay = INFINITE - 1;
    }
    else {
        milliSecDelay = ( DWORD ) ( ( seconds * mSecPerSec ) + 0.5 );
        if ( milliSecDelay == 0 ) {
            milliSecDelay = 1;
        }
    }
    Sleep ( milliSecDelay );
}

> -----Original Message-----
> From: [email protected] [mailto:[email protected]]
> On Behalf Of Ralph Lange
> Sent: Wednesday, June 06, 2012 4:31 AM
> To: EPICS Core Talk
> Cc: Dirk Zimoch
> Subject: epicsTimer and rounding
> 
> Hi,
> 
> While helping us with finding a weird behavior in a StreamDevice based
> interface, Dirk Zimoch found the following:
> 
> When adapting the expire period (requested as a double value in seconds)
> to the matching amount of sleep quantums, the current implementation of
> epicsTimer rounds mathematically (line 71 of timer.cpp subtracts half a
> quantum from the expire time). So, for requested expire periods in the
> same order as the quantum, the actual expire period used by the timer is
> up to 100% shorter than the requested period.
> 
> In the section about epicsTimer, the App Developers' does not make a
> statement about the relation between requested and actual period.
> 
> IMHO, the actual expire period should always be equal or larger than the
> requested value, i.e. the implementation should always round up when
> converting to quantums. (And the doc should mention this behavior.)
> 
> What do you think?
> 
> Cheers,
> ~Ralph



Replies:
Re: epicsTimer and rounding Ralph Lange
References:
epicsTimer and rounding Ralph Lange

Navigate by Date:
Prev: epicsTimer and rounding Ralph Lange
Next: "spinlock" API Michael Davidsaver
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: epicsTimer and rounding Ralph Lange
Next: Re: epicsTimer and rounding Ralph Lange
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 26 Nov 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·