Linux high-precision time series (sleep, usleep, nanosleep)

Source: Internet
Author: User
Tags usleep
Article Title: Linux high-precision timing (sleep, usleep, nanosleep ). Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.

First of all, I will say that it is not guaranteed that the process you run in user-mode can accurately control the time sequence because Linux is a multi-job environment. the progress you are performing will be paused for about 10 ms to several seconds at any time for various reasons (when the system load is very high ). however, for most applications that use I/O Ports, the latency is actually nothing. to shorten the delay time, you must use the function nice to set your progress in execution to a high priority (see nice (2) instructions) or use the real-time scheduling (see the following ).

If you want to obtain a time sequence that is more accurate than the process in the user-mode, there are some ways for you) to support the 'real' schedule. linux 2.x supports real-time scheduling in the software mode. For details, see sched_setscheduler (2) instructions. there is a special real-time schedule of core supporting hardware;

(Sleeping): sleep () and usleep ()

Now, let's start a simple time series call. the best way to delay a few seconds is to use the function sleep (). to delay at least dozens of milliseconds (10 MS seems to be the shortest delay), the form of usleep () should be available. these functions allow the CPU to be used for other processes (''take a rest ''), so there is no waste of CPU time. for details, see the description files of sleep (3) and usleep (3.

If the CPU usage is granted, the time delay is about 50 milliseconds (depending on the speed of the processor and machine, and the system load), too much CPU time is wasted, because the Linux scheduler (sched) usually takes at least 10-30 milliseconds before sending control to your process. therefore, for a short delay, the result of using the function usleep (3) is usually greater than the value specified in the parameter, which is about 10 ms.

Nanosleep ()

In a series of Linux 2.0.x core releases, there is a new system call and nanosleep () (see the description file of nanosleep (2 ), it allows you to rest or delay a short period of time (several microseconds or more ).

If the delay time <= 2 MS, if (and only if) the trip you are executing (process) sets the real-time schedule of the software (that is, using the function tt/sched_setscheduler () /). When calling the cool-form nanosleep (), it does not use a busy loop to delay the time; it means it will let the CPU use right rest like the lool-form usleep.

This busy loop is achieved using the correspondence udelay () (the core internal correspondence that a driver usually uses) and the BogoMips value (BogoMips can accurately measure the speed of this busy loop) to calculate the length of the loop latency. for details about how to perform the operation, see/usr/include/asm/delay. h ).

Latency using I/O Ports

Another method of delay in several microseconds is to use the I/O port. it is to input or output any byte data from the port address 0x80 (refer to the previous section). The waiting time should be almost 1 microsecond, depending on the type and speed of your processor. if you want to delay several microseconds, you can do this operation several times. output Data to this port address on any standard machine should not be defective (and some core device drivers are also using it ). the syntax of {in | out} [bw] _ p () is to use this method to produce time delay (see the file asm/io. h ).

In fact, an I/O PORT command with the IP address □circumference 0-0x3ff takes almost 1 microsecond, so if you want to do this, for example, directly use the parallel port, you only need to add several inb () functions to read byte data from the address □.

Latency using a combination of languages

If you know the processor type and clock speed of the machine where the execution program is located, You can execute some combined language commands to get a short delay (but remember, you are in the process) will be paused at any time, so sometimes the delay will be longer than the actual time ). as shown in the following table, the speed of the internal processor determines the number of clock cycles to use. For example, a 50 MHz processor (486DX-50 or 486DX2-50 ), A clock cycle takes 1/50000000 seconds (= 200 Nai seconds ).

Instruction i386 Number of clock periods i486 Number of clock periods nop 3 1 xchg % ax, % ax 3 3or % ax, % ax 2 1mov % ax, % ax 2 1add % ax, 0 2 1

(Sorry, I don't know about Pentiums. Maybe it's close to IMG. I cannot find instructions that only take one clock cycle on i386. if you can use a command that takes a clock cycle, or you can use a new processor of the pipeline technology to shorten the time .)

The commands nop and xchg in the above table should have no bad results. the command may change the content of the Flag store at the end, but it does not matter because gcc will handle it. the nop command is a good choice.

To use these commands in your program, you must use asm ("instruction "). command syntax is like the usage in the preceding table; if you want to use multiple commands in a single asm () statement, you can use semicolons to separate them. for example, asm ("nop; nop") executes four nop commands, four clock cycles will be delayed in the i486 or Pentium processor (or the i386 will delay 12 clock cycles ).

Gcc translates asm () into a single-line combined language code, so there is no call function load.

In Intel x86 architecture, there cannot be a shorter latency than a clock cycle.

Use Function rdtsc on Pentiums Processor

For the Pentiums processor, you can use the following C-language code to obtain the number of clock cycles that have elapsed since the last reboot:

--------------------------------------------------------------------------------

Extern _ inline _ unsigned long int rdtsc () {unsigned long int x; _ asm _ volatile (". byte 0x0f, 0x31 ":" = A "(x); return x ;}

--------------------------------------------------------------------------------

You can refer to this value to delay the number of clock cycles you want.

If you want time to be accurate to one second, using the function time () is perhaps the simplest method. to make the time more accurate, the function gettimeofday () can be precise to microseconds (but as described earlier, it will be affected by the CPU schedule ). as for the Pentiums processor, the above code snippet can be precise to a clock cycle.

If you want the process to be executed to be notified after a period of time, you must use the form setitimer () or alarm (). for more information, see the description file.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.