Re: brief naps (aftermath)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On Tue, 4 Nov 2003 15:18:00 +0200, Gilad Ben-Yossef [EMAIL PROTECTED] wrote: On Tuesday 04 November 2003 14:43, Ehud Karni wrote: I tested the select call on various machines. 1. It is not accurate enough (2 ms deviations). Yes it does, you don't seem to use sched_setscheduler in your test program to give your proccess real time priority. setpriority only changes the nice level of the proccess. If you want real time guantees (which you do here) you need to ask the kernel to subject your proccess to real time scheduling. See test results below. 2. It can not be used for delays 10 ms. Unless you recompile the kernel, you are correct. I enhanced my test program by adding the scheduler priority like this: #include sched.h struct sched_param scd_prm ; scd_prm.sched_priority = 10 ; /* anything greater than 0 */ sched_setscheduler ( 0 , SCHED_RR , scd_prm ) ; /* try to set scheduler policy and priority */ setpriority ( PRIO_PROCESS , 0 , atoi ( argv [ 2 ] ) ) ;/* set nice priority (no check) */ fprintf ( stderr , Run at %d sched priority, %d nice , sched_getscheduler ( 0 ) ,/* get schedule priority */ getpriority ( PRIO_PROCESS , 0 ) ) ; /* get process priority */ I tested the select sleep and my conclusions are: 1. Even with Real time priority it is accurate to within 0.1 mill seconds (see 1st set of results). 2. The granularity is 10 ms even for times 10 ms. Here are some of the results: Run at 2 sched priority, -20 nicesleeped 37076 usec * 100 times, Elapsed 3995 msecs Run at 2 sched priority, -20 nicesleeped 37076 usec * 100 times, Elapsed 3995 msecs Run at 2 sched priority, -20 nicesleeped 37076 usec * 100 times, Elapsed 3998 msecs Run at 2 sched priority, -20 nicesleeped 37076 usec * 100 times, Elapsed 4000 msecs Run at 2 sched priority, -20 nicesleeped 37076 usec * 100 times, Elapsed 3992 msecs Run at 2 sched priority, -20 nicesleeped 37076 usec * 100 times, Elapsed 3993 msecs Run at 2 sched priority, -20 nicesleeped 37076 usec * 100 times, Elapsed 3995 msecs Run at 2 sched priority, -20 nicesleeped 1 usec * 100 times, Elapsed 997 msecs Run at 2 sched priority, -20 nicesleeped 38 usec * 100 times, Elapsed 991 msecs Run at 2 sched priority, -20 nicesleeped 987 usec * 100 times, Elapsed 1000 msecs Run at 2 sched priority, -20 nicesleeped 1987 usec * 100 times, Elapsed 992 msecs Run at 2 sched priority, -20 nicesleeped 9876 usec * 100 times, Elapsed 1000 msecs Run at 2 sched priority, -20 nicesleeped 19876 usec * 100 times, Elapsed 1997 msecs Run at 2 sched priority, -20 nicesleeped 18076 usec * 100 times, Elapsed 1995 msecs Run at 2 sched priority, -20 nicesleeped 19076 usec * 100 times, Elapsed 1991 msecs Run at 2 sched priority, -20 nicesleeped 37076 usec * 100 times, Elapsed 3999 msecs Run at 2 sched priority, -20 nicesleeped 36076 usec * 100 times, Elapsed 3994 msecs Run at 2 sched priority, -20 nicesleeped 35076 usec * 100 times, Elapsed 3993 msecs Run at 2 sched priority, -20 nicesleeped 34076 usec * 100 times, Elapsed 3998 msecs Run at 2 sched priority, -20 nicesleeped 33076 usec * 100 times, Elapsed 3997 msecs Run at 2 sched priority, -20 nicesleeped 32076 usec * 100 times, Elapsed 3993 msecs Run at 2 sched priority, -20 nicesleeped 31076 usec * 100 times, Elapsed 3993 msecs Run at 2 sched priority, -20 nicesleeped 30076 usec * 100 times, Elapsed 3993 msecs Run at 2 sched priority, -20 nicesleeped 29076 usec * 100 times, Elapsed 2998 msecs Run at 2 sched priority, -20 nicesleeped 29976 usec * 100 times, Elapsed 2994 msecs Ehud. - -- Ehud Karni Tel: +972-3-7966-561 /\ Mivtach - Simon Fax: +972-3-7966-667 \ / ASCII Ribbon Campaign Insurance agencies (USA) voice mail and X Against HTML Mail http://www.mvs.co.il FAX: 1-815-5509341 / \ GnuPG: 98EA398D http://www.keyserver.net/Better Safe Than Sorry -BEGIN PGP SIGNATURE- Comment: use http://www.keyserver.net/ to get my key (and others) iD8DBQE/qOYBLFvTvpjqOY0RAqs0AJ9PszCyABgW2GS4Xq0X7nZ5yOHWjgCfTtap OgFidx/1HGIC12IIghyG8Ro= =laIM -END PGP SIGNATURE- = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: brief naps (aftermath)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On Mon, 03 Nov 2003 12:30:15 +0200, Ami Chayun [EMAIL PROTECTED] wrote: A couple of results: 1) The rdtscll Pentium instruction (Eran's answer) is very useful. It's super accurate and right now I decided to use it mostly to benchmark other solutions, and to estimate the CPU frequency with a fancy version of - CODE rdtscll(time1); sleep(1); rdtscll(time2); frequency = time2 - time1; /CODE The use of rdtscll as a long sleep function (above 1 msec) is not very recommended, since even with the nops, it hogs most of the CPU. I don't understand why you need to know the CPU speed (see my tight loop below). The sleep call is exact to 10 milli seconds at most. 2) The select method is very CPU friendly. It is also the way microsecond sleep is implemented in xmms and alsa (xmms_usleep, and doSleep in alsa) XMMS's code: unsigned long usec... CODE struct timeval tv; tv.tv_sec = usec / 100; usec -= tv.tv_sec * 100; tv.tv_usec = usec; select(0, NULL, NULL, NULL, tv); /CODE It's pretty stable for time periods of ~1 msec and above. I tested the select call on various machines. 1. It is not accurate enough (2 ms deviations). 2. It can not be used for delays 10 ms. This is the program used to test the select call: #include stdio.h #include unistd.h #include stdlib.h #include sys/time.h /* for gettimeofday */ #include sys/resource.h /* for setpriority */ void my_usleep ( int u_sec ) ; int main ( int argc, char *argv[] ) { int usec = 1 , cnt = 0 , elapsed , loop = 1000 ; struct timeval bfr, aftr ; /* computer time before / after */ setpriority ( PRIO_PROCESS , 0 , atoi ( argv [ 2 ] ) ) ;/* setpriority (no check) */ fprintf ( stderr , Run at %d priority , getpriority ( PRIO_PROCESS , 0 ) ) ; /* get process priority */ usec = atoi ( argv [ 1 ] ) ;/* time to sleep (Milli seconds) */ gettimeofday ( bfr , NULL ) ; /* computer time - before */ while ( cnt loop ) { my_usleep ( usec ) ;/* sleep usec micro seconds (mine) */ cnt++ ; } gettimeofday ( aftr , NULL ) ;/* computer time - after */ elapsed = ( aftr.tv_sec - bfr.tv_sec ) * 1000 + ( aftr.tv_usec - bfr.tv_usec ) / 1000 ; fprintf ( stderr , sleeped %d usec * %d times, Elapsed %d msecs\n , usec , cnt , elapsed ) ; return ( 0 ) ; } /*=*/ void my_usleep ( int u_sec ) { struct timeval wt ; wt.tv_sec = u_sec / 100 ; wt.tv_usec = u_sec % 100 ; /* for select */ if ( u_sec 0 ) select(0, NULL, NULL, NULL, wt); /* sleep (release cpu) */ } /*=*/ In the end I think we'll implement some sort of combination of all the 3 solutions including the kernel HZ value (thanks Gilad, the link was great!). Since the delay doesn't change often, we have the freedom to decide which of the 3 functions is best during runtime, and select it. Here is my solution (my_usleep) embedded in a test program. This function has an accuracy of about 1 micro second. /* Sleep for arg1 micro seconds 10**N times, and print statistics arg2 is priority (-20 .. 19) If arg3 is given, call system usleep. */ #include stdio.h #include unistd.h #include stdlib.h #include sys/time.h /* for gettimeofday */ #include sys/resource.h /* for setpriority */ void my_usleep ( int u_sec ) ; /* my usleep */ int main ( int argc, char *argv[] ) { int usec , cnt = 0 , elapsed , loop = 1 ; struct timeval bfr, aftr ; /* computer time before / after */ setpriority ( PRIO_PROCESS , 0 , atoi ( argv [ 2 ] ) ) ;/* setpriority (no check) */ fprintf ( stderr , Run at %d priority , getpriority ( PRIO_PROCESS , 0 ) ) ; /* get process priority */ usec = atoi ( argv [ 1 ] ) ;/* time to sleep (milli seconds) */ if ( usec 20 ) loop = 1 ; else while ( ( usec * loop ) 200 ) /* total time 2 seconds */ loop /= 10 ; gettimeofday ( bfr , NULL ) ; /* computer time - before */ while ( cnt loop ) { if ( argc 4 ) my_usleep ( usec ) ;/* sleep usec micro seconds (mine) */ else usleep ( usec ) ; /* sleep usec micro seconds (standard) */ cnt ++ ; } gettimeofday ( aftr , NULL ) ;/* computer time - after */ elapsed = ( aftr.tv_sec - bfr.tv_sec ) * 1000 + ( aftr.tv_usec - bfr.tv_usec ) / 1000 ; fprintf ( stderr , sleeped %d usec
Re: brief naps (aftermath)
On Tuesday 04 November 2003 14:43, Ehud Karni wrote: I tested the select call on various machines. 1. It is not accurate enough (2 ms deviations). Yes it does, you don't seem to use sched_setscheduler in your test program to give your proccess real time priority. setpriority only changes the nice level of the proccess. If you want real time guantees (which you do here) you need to ask the kernel to subject your proccess to real time scheduling. 2. It can not be used for delays 10 ms. Unless you recompile the kernel, you are correct. Here is my solution (my_usleep) embedded in a test program. This function has an accuracy of about 1 micro second. No it doesn't. Without real time priority the select is not guranteed to wake up on time. You can easily miss your mark and over sleep. Gilad -- Gilad Ben-Yossef [EMAIL PROTECTED] Codefidence. A name you can trust (tm) http://www.codefidence.com Half of one of my eyes is already open. I'm going to make coffee now... -- Kathi 16:08:04 = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: brief naps (aftermath)
If you don't set your process to SCHED_FIFO or SCHED_RR (only possible as root) and give it realtime priority, you can never be sure to wake up in time (see Gilad's message in the thread). From my understanding, if you recompile the kernel with HZ value higher than 1000, you can use nanosleep or usleep, without all the fancy tricks. But if your kernel runs in 10 msec quanta, you will have to use cpu tight loops or other realtime solutions. In that case you are correct, and select cannot give you delay of less than 10 msec. Ami On Tue, 2003-11-04 at 15:18, Gilad Ben-Yossef wrote: On Tuesday 04 November 2003 14:43, Ehud Karni wrote: I tested the select call on various machines. 1. It is not accurate enough (2 ms deviations). Yes it does, you don't seem to use sched_setscheduler in your test program to give your proccess real time priority. setpriority only changes the nice level of the proccess. If you want real time guantees (which you do here) you need to ask the kernel to subject your proccess to real time scheduling. 2. It can not be used for delays 10 ms. Unless you recompile the kernel, you are correct. Here is my solution (my_usleep) embedded in a test program. This function has an accuracy of about 1 micro second. No it doesn't. Without real time priority the select is not guranteed to wake up on time. You can easily miss your mark and over sleep. Gilad = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
RE: brief naps (aftermath)
Hi all, First of all, I'd like to thank everyone that have answered, I never expected so many solutions :) A couple of results: 1) The rdtscll Pentium instruction (Eran's answer) is very useful. It's super accurate and right now I decided to use it mostly to benchmark other solutions, and to estimate the CPU frequency with a fancy version of - CODE rdtscll(time1); sleep(1); rdtscll(time2); frequency = time2 - time1; /CODE The use of rdtscll as a long sleep function (above 1 msec) is not very recommended, since even with the nops, it hogs most of the CPU. 2) The select method is very CPU friendly. It is also the way microsecond sleep is implemented in xmms and alsa (xmms_usleep, and doSleep in alsa) XMMS's code: unsigned long usec... CODE struct timeval tv; tv.tv_sec = usec / 100; usec -= tv.tv_sec * 100; tv.tv_usec = usec; select(0, NULL, NULL, NULL, tv); /CODE It's pretty stable for time periods of ~1 msec and above. In the end I think we'll implement some sort of combination of all the 3 solutions including the kernel HZ value (thanks Gilad, the link was great!). Since the delay doesn't change often, we have the freedom to decide which of the 3 functions is best during runtime, and select it. Hope this will help others. Ami = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
RE: brief naps
There is no problem whatsoever to set the clock to other speeds. , it's jsut a #define in the kernel sources (look for HZ) In kernel 2.6.x this #define is configurable via the regular make *config facility. For 2.4.x there's a patch that accomplish the same and I've used it for several projects with not problem. For 2.2 you can just change the value of the HZ define yourself. A value of 1024 is recomended. Good to hear. It indeed a good feature. With this patch, nanosleep (and even usleep) will give you what you want. It can, unless one need various different timings with low common denominator ... Another issue is periodical vs. random activities. While for periodical tasks you can set the clock easily, a task that activated from outside (some interrupt from a device) and then send a signal (discrete) and need to wait up to 1mSec (as timeout if no response) can't do with 1000Hz. If you tolerate 100uSec it can do with 1Hz clock but no one want such a clock - it will kill the system. For such a random timing events you need an auxiliary timer. So, it depend of the application characteristics and allowed jittering. *IMPORTANT* If timing is important to you as it seems it does, make sure to use sched_setscheduler() and sched_setpriority() to give real time priority to the proccess that requires these short sleeps, otherwise NONE of the methods suggested above (by me or other people) is guranteed to work. In fact, it's guranteed not to work :-) True. Notes : 1. Interrupt masking can create a latency. Make sure you remove all unnecessary services and applications. 2. If periodic task is needed, read some fast clock right before you calculations to find jittering and do the correct extrapolations (i.e. tick-ISR-semaphore-user level thread-your algorithm may take different time each cycle). 3. If activating auxiliary timer that need arming every time make sure you do it as soon as posible (in the periodic case - in the ISR itself) so you won't have time sweeping. Good luck. This e-mail message has been sent by Elbit Systems Ltd. and is for the use of the intended recipients only. The message may contain privileged or confidential information . If you are not the intended recipient you are hereby notified that any use, distribution or copying of this communication is strictly prohibited, and you are requested to delete the e-mail and any attachments and notify the sender immediately. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
RE: brief naps
Hi, I have a question regarding short sleeps (under 10 millisec). 1. Busy wait : It is like the story about Abed (in Yalkut Hakzavim) - Abed could throw a grenade to 80 meters. Once he needed to throw to 50 meters he stepped back 30 ... 2. You can't do idle wait less then 10mSec. The clock in PC is set to that value (probably can be manipulate, but it will result so many things so better not). It mean interrupt at 100Hz. Accurate clock is not good enough - you need an alarm clock; a timer, that will give you an interrupt as you choose. You can by such PCI cards, just check if it supported. Now, once you have an interrupt at you choice, you can either execute your needs at ISR level, or, using the select (man 2 select) with a pipe descriptor to which the ISR write. Note that here you need preemption and R.T. priority like Eran wrote. Feel free to contact me for more details. Iftach (Orna - I want royalties). This e-mail message has been sent by Elbit Systems Ltd. and is for the use of the intended recipients only. The message may contain privileged or confidential information . If you are not the intended recipient you are hereby notified that any use, distribution or copying of this communication is strictly prohibited, and you are requested to delete the e-mail and any attachments and notify the sender immediately. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: brief naps
On Friday 31 October 2003 10:01, Iftach Hyams wrote: Hi, I have a question regarding short sleeps (under 10 millisec). 1. Busy wait : It is like the story about Abed (in Yalkut Hakzavim) - Abed could throw a grenade to 80 meters. Once he needed to throw to 50 meters he stepped back 30 ... 2. You can't do idle wait less then 10mSec. The clock in PC is set to that value (probably can be manipulate, but it will result so many things so better not). There is no problem whatsoever to set the clock to other speeds. , it's jsut a #define in the kernel sources (look for HZ) In kernel 2.6.x this #define is configurable via the regular make *config facility. For 2.4.x there's a patch that accomplish the same and I've used it for several projects with not problem. For 2.2 you can just change the value of the HZ define yourself. A value of 1024 is recomended. The 2.4 patch/2.6. feature is discussed by it's author Robert Love here: http://kerneltrap.org/node/view/464/1466 The patch also turns jiffies to a 64 bit variable to avoid the problem of jiffie warp around that might bite you with high HZA values otherwise. With this patch, nanosleep (and even usleep) will give you what you want. *IMPORTANT* If timing is important to you as it seems it does, make sure to use sched_setscheduler() and sched_setpriority() to give real time priority to the proccess that requires these short sleeps, otherwise NONE of the methods suggested above (by me or other people) is guranteed to work. In fact, it's guranteed not to work :-) You owe the Linux real time oracle a jiffie. Cheers, Gilad -- Gilad Ben-Yossef [EMAIL PROTECTED] http://benyossef.com = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: brief naps
On Thu, Oct 30, 2003 at 10:49:38PM +0200, Ami Chayun wrote: Hi, I have a question regarding short sleeps (under 10 millisec). I require to implement sleep with about 1-10 microsec accuracy (that's no problem), but I require to sleep for times ranging between 1 microsec to 1 millisec. usleep? The usleep() function suspends execution of the calling process for (at least) usec microseconds. The sleep may be lengthened slightly by any system activity or by the time spent processing the call or by the granularity of system timers. -- Shaul Karl,shaulk @ actcom . net . il = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: brief naps
usleep gives you usec accuracy, but the system scheduler can't give you resolution less than 10 millisec quanta... Please correct me if I'm wrong. Ami On Friday 31 October 2003 00:34, you wrote: On Thu, Oct 30, 2003 at 10:49:38PM +0200, Ami Chayun wrote: Hi, I have a question regarding short sleeps (under 10 millisec). I require to implement sleep with about 1-10 microsec accuracy (that's no problem), but I require to sleep for times ranging between 1 microsec to 1 millisec. usleep? The usleep() function suspends execution of the calling process for (at least) usec microseconds. The sleep may be lengthened slightly by any system activity or by the time spent processing the call or by the granularity of system timers. = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: brief naps
On 2003/10/31 00:34, Shaul Karl wrote: On Thu, Oct 30, 2003 at 10:49:38PM +0200, Ami Chayun wrote: I have a question regarding short sleeps (under 10 millisec). I require to implement sleep with about 1-10 microsec accuracy (that's no problem), but I require to sleep for times ranging between 1 microsec to 1 millisec. usleep? Its manpage states: This function is obsolete. Use nanosleep(2) or setitimer(2) instead. But nanosleep(2) won't do the trick. If the machine is idle, nanosleep(2) will cause the kernel to issue a HLT instruction from which will wake up only upon the next interrupt; the only interrupt that's guaranteed to occur is the timer interrupt, up to 1/HZ = 10 millisec (in kernel 2.4) later -- much worse than the desired accuracy of 1-10. Similarly, if some other task takes over the CPU then it might be preempted only at the next timer interrupt. nanosleep(2) *can* perform accurate busy-wait delays, but will do so only for for pauses up to 2ms and if the process is scheduled under a real-time policy like SCHED_FIFO or SCHED_RR. I happened to look this up in the 2.4 kernel source and yup, that's exactly what it does. So the solution is to do a busy-wait loop by yourself, in userspace. Modern x86 CPUs have an RDTSC instruction which reads a CPU cycle count -- this is the best way to make time measurements in the relevant scale. The code should look something like this (courtesy of the kernel source): #define rdtscl(low) asm volatile(rdtsc : =a (low) : : edx) #define rep_nop asm volatile(rep;nop) static void rdtsc_delay(unsigned long loops) { unsigned long bclock, now; rdtscl(bclock); do { rep_nop(); // reduce CPU power consumption rdtscl(now); } while ((now-bclock) loops); } If you need loops2^32, either wrap it by an outer loop or replace all longs by long longs and replace rdtscl by #define rdtscll(val) asm volatile(rdtsc : =A (val)) You can find the number of loops per second by doing some calibration at program startup (be careful if it's a laptop with variable CPU speed). Eran = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]
Re: brief naps
On Thu, 30 Oct 2003, Ami Chayun wrote: Hi, I have a question regarding short sleeps (under 10 millisec). I require to implement sleep with about 1-10 microsec accuracy (that's no problem), but I require to sleep for times ranging between 1 microsec to 1 millisec. From my understanding I have two options: 1) CPU tight loops, and count CPU cycles. 2) Use some sort of realtime clock. (Since my code uses a lot of CPU already, I would really like to avoid method 1.) Can anyone point me to some examples on any (or both...) of the methods, pros and cons of each will be most welcome :-) Thanks, Ami I once got the following answer (as to sleep for less than 30 n) from Iftach Hyams, who deals with RT systems (he also gave a lecture about it in Haifux: http://www.haifux.org/lectures/78/ I admit I do not fully understand the answer, but maybe it will help you: ANSWER BY IFTACH The solution is as follow (I implemented it in VxWorks 5.4 but the idea is, if you just implement pipes correctly and they support select) : (It is a part of code that waits for an acknowledge on in a socket, but you can only delay a short time). My function: ... fd_set rdfs; int myPipe; /* Linux need an array - man pipe */ createPipe (myPipe); FD_ZERO (rdfs); FD_SET (acknowledgeSocket, rdfs); /* Register socket */ FD_SET (myPipe, rdfs); /* Register pipe */ ioctl (pipeFile, FIOFLUSH, 0); /* Discard previous data */ send (...) /* Send something which cause an acknowledge */ armTimer (time ); socketStatus = select (FD_SETSIZE,rdfs,NULL,NULL,NULL); if (FD_ISSET (acknowledgeSocket,rdfs)) ... ISR service : void timerExpired (int pipeFile) { /* Write anything to the pipe so the select will be unlocked */ write (pipeFile,Something,1); } Register an ISR: isrRegister ((void*)timerExpired,*pipeFile); Emphasizes : - Make sure the pipes have the select feature. - Timers are not portable. Each system has its own implementation. - The context switch delay has its own latency. You must measure it if the delays are very small (milliseconds are not small). - Do everything before the send or after the select so the waiting time will be consistent and minimal (beyond the timers delay). /ANSWER BY IFTACH = To unsubscribe, send mail to [EMAIL PROTECTED] with the word unsubscribe in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]