EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: epicsThreadSleep() and epicsThreadSleepQuantum()
From: "Jeff Hill" <[email protected]>
To: "'Mark Rivers'" <[email protected]>, <[email protected]>
Date: Mon, 29 Sep 2008 17:03:09 -0600
Hi Mark,

See also my attempt at sleep quantum measurement which is (it was relocated
in recent R3.14 releases) in "epicsThreadPerform.cpp" under
"<base>/src/libCom/test". I probably spent all of an hour or two on this
test code so I wouldn't be shocked if there were still some improvements
that could be made. So have a look at that code and let me know what you
think.

Some Notes:
1) I suspect that timestamps are more accurate on the win32 native port when
compared with the cygwin port.
2) Combining all of the sleep calls together inside of a for loop and
bracketing them all, for loop begin and end, with time stamp fetches isn't a
particularly accurate way to measure the quantum because you tend to get
aligned in time with the OS's scheduling quantum interrupt, and we might not
end up with a good estimate of real world sleep intervals.

C:\...\base\src\libCom\test\O.WIN32-x86>epicsThreadPerform
testPriority main error expected from epicsThreadSetPriority
    id 001B9BB0 old 49 new 49
testPriority thread
    id 001B9DB8 old 50 new 50
Estimating sleep quantum..........done
Estimating sleep quantum..........done
The epicsThreadSleepQuantum() call returns 0.015600 sec.
This doesnt match the quantum estimate of 0.010947 sec within 10%.
It takes 0.030659 micro sec to call epicsThreadGetIdSelf ()
epicsThreadPrivateGet() takes 0.017769 microseconds

C:\...\base\src\libCom\test\O.cygwin-x86>epicsThreadPerform
epicsThreadSetPriority called by non epics thread
epicsThreadSetPriority called by non epics thread
testPriority main error expected from epicsThreadSetPriority
    id 0x10460260 old 0 new 0
testPriority thread
    id 0x10472580 old 50 new 99
Estimating sleep quantum..........done
Estimating sleep quantum..........done
The epicsThreadSleepQuantum() call returns 0.001000 sec.
This doesnt match the quantum estimate of 0.017720 sec within 10%.
epicsThreadSleep (   1.000000 ) delay err   0.014000 sec
epicsThreadSleep (   0.500000 ) delay err   0.014000 sec
epicsThreadSleep (   0.250000 ) delay err   0.016000 sec
epicsThreadSleep (   0.125000 ) delay err   0.015000 sec
epicsThreadSleep (   0.062500 ) delay err   0.015500 sec
epicsThreadSleep (   0.031250 ) delay err   0.015750 sec
epicsThreadSleep (   0.015625 ) delay err   0.015375 sec
epicsThreadSleep (   0.007812 ) delay err   0.008188 sec
epicsThreadSleep (   0.003906 ) delay err   0.011094 sec
epicsThreadSleep (   0.001953 ) delay err   0.014047 sec
epicsThreadSleep (   0.000977 ) delay err   0.014023 sec
epicsThreadSleep (   0.000488 ) delay err   0.015512 sec
epicsThreadSleep (   0.000244 ) delay err   0.015756 sec
epicsThreadSleep (   0.000122 ) delay err   0.014878 sec
epicsThreadSleep (   0.000061 ) delay err   0.015939 sec
epicsThreadSleep (   0.000031 ) delay err   0.014969 sec
epicsThreadSleep (   0.000015 ) delay err   0.015985 sec
epicsThreadSleep (   0.000008 ) delay err   0.015992 sec
epicsThreadSleep (   0.000004 ) delay err   0.014996 sec
epicsThreadSleep (   0.000002 ) delay err   0.015998 sec
Average sleep delay error was 0.013952 sec
It takes 0.150000 micro sec to call epicsThreadGetIdSelf ()
epicsThreadPrivateGet() takes 0.000000 microseconds

Thanks your help,

Jeff

> -----Original Message-----
> From: [email protected] [mailto:[email protected]]
> On Behalf Of Mark Rivers
> Sent: Monday, September 29, 2008 1:57 PM
> To: [email protected]
> Subject: epicsThreadSleep() and epicsThreadSleepQuantum()
> 
> Folks,
> 
> I've just discovered a problem relating to epicsThreadSleep() and
> epicsThreadSleepQuantum() on linux-x86 and win32-x86.
> 
> Here is the documentation from the Application Developer's Guide
> (3.14.9) for epicsThreadSleepQuantum:
> 
> ********************************************
> epicsThreadSleepQuantum
> 
> This function returns the minimum slumber interval obtainable with
> epicsThreadSleep() in seconds. On most OS there is a system scheduler
> interrupt
> interval which determines the value of this parameter. Knowledge of this
> parameter is used by the various components of EPICS to improve
> scheduling of software tasks in time when the reduction of average time
> scheduling errors is important. If this parameter is unknown or is
> unpredictable for a particular OS then it is safe to return zero.
> *******************************************
> 
> I was seeing some behavior I did not expect in a Windows IOC, so I wrote
> a little test program that I ran on Linux and Windows.  This program
> simply prints out the value of epicsThreadSleepQuantum, and then sleeps
> for various amounts of time, ranging from .0001 second to .020 seconds,
> and reports the actual length of the sleep.  These sleeps are done in a
> loop 1000 times to improve the precision.
> 
> Here is the program, testTimer.c:
> 
> *********************************************
> #include <stdio.h>
> #include <epicsThread.h>
> #include <epicsTime.h>
> 
> 
> #define MAX_TIMES 8
> #define MAX_LOOPS 1000
> 
> int main(int argc, char **argv)
> {
>     double times[MAX_TIMES] = {.0001, .0002, .0005, .001, .002, .005,
> .010, .020};
>     int iloop, itime;
>     epicsTimeStamp startTime, endTime;
>     double elapsedTime;
> 
>     printf("epicsThreadSleepQuantum=%f\n", epicsThreadSleepQuantum());
> 
>     for (itime=0; itime<MAX_TIMES; itime++) {
>         epicsTimeGetCurrent(&startTime);
>         for (iloop=0; iloop<MAX_LOOPS; iloop++) {
>             epicsThreadSleep(times[itime]);
>         }
>         epicsTimeGetCurrent(&endTime);
>         elapsedTime = epicsTimeDiffInSeconds(&endTime, &startTime);
>         printf("Elapsed time to sleep for %f seconds %d times=%f\n",
>             times[itime], MAX_LOOPS, elapsedTime);
>     }
>     return(0);
> }
> ********************************************
> 
> Here are the results on linux-x86:
> 
> ********************************
> corvette:1-2/ADApp/simDetectorSrc>../../bin/linux-x86/testTimer
> epicsThreadSleepQuantum=0.010000
> Elapsed time to sleep for 0.000100 seconds 1000 times=0.109260
> Elapsed time to sleep for 0.000200 seconds 1000 times=0.209482
> Elapsed time to sleep for 0.000500 seconds 1000 times=0.509600
> Elapsed time to sleep for 0.001000 seconds 1000 times=1.010766
> Elapsed time to sleep for 0.002000 seconds 1000 times=2.010574
> Elapsed time to sleep for 0.005000 seconds 1000 times=5.011690
> Elapsed time to sleep for 0.010000 seconds 1000 times=10.012555
> Elapsed time to sleep for 0.020000 seconds 1000 times=20.014360
> *******************************
> 
> Note that epicsThreadSleepQuantum is 10 milliseconds.  However, this is
> NOT the actual "minimum slumber interval obtainable" with
> epicsThreadSleep.  We are able to sleep for 100 microseconds quite
> accurately with epicsThreadSleep().
> 
> Here are the results for win32-x86:
> 
> ************************************
> $ ../../bin/win32-x86/testTimer.exe
> epicsThreadSleepQuantum=0.015625
> Elapsed time to sleep for 0.000100 seconds 1000 times=1.953120
> Elapsed time to sleep for 0.000200 seconds 1000 times=1.956814
> Elapsed time to sleep for 0.000500 seconds 1000 times=1.964528
> Elapsed time to sleep for 0.001000 seconds 1000 times=1.961861
> Elapsed time to sleep for 0.002000 seconds 1000 times=2.931468
> Elapsed time to sleep for 0.005000 seconds 1000 times=5.860293
> Elapsed time to sleep for 0.010000 seconds 1000 times=10.748225
> Elapsed time to sleep for 0.020000 seconds 1000 times=20.517168
> ***********************************
> 
> Note that epicsThreadSleepQuantum is 15.6 milliseconds.  However, again
> this is NOT the actual "minimum slumber interval obtainable" with
> epicsThreadSleep.  We are able to sleep for about 1 millisecond with
> epicsThreadSleep().  Requests for intervals of 1 millisecond or less
> result in the same time.
> 
> These tests were done under EPICS 3.14.8.2.  I have not yet installed a
> more recent version, so I can't be sure if this behavior has changed.
> However, I don't see anything in the release notes for 3.14.9 or 3.14.10
> about epicsThreadSleep.
> 
> This is rather important, because I know there are EPICS applications
> that assume that epicsThreadSleepQuantum is truly the minimum time it
> makes sense to request a sleep interval for.  This is clearly not the
> case on Windows and Linux, so perhaps epicsThreadSleepQuantum needs to
> be rewritten for those platforms.
> 
> Mark
> 
> 
> 



References:
epicsThreadSleep() and epicsThreadSleepQuantum() Mark Rivers

Navigate by Date:
Prev: Base R3.14.10-RC1 Released Andrew Johnson
Next: Re: epicsThreadSleep() and epicsThreadSleepQuantum() Andrew Johnson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: epicsThreadSleep() and epicsThreadSleepQuantum() David Dudley
Next: Re: epicsThreadSleep() and epicsThreadSleepQuantum() Andrew Johnson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·