Experimental Physics and Industrial Control System
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
<2012>
2013
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
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024