In-depth analysis of time measurement in Linux

Source: Internet
Author: User

 


1) ANSI clock functions

1) Overview:
Clock_t is the return value type of the clock function. It is divided by clocks_per_sec to get the time. Generally, two clock functions are used to calculate the time when the process runs.

ANSI clock has three problems:
1) if it exceeds one hour, it will cause overflow.
2) The function clock does not consider the usage of the CPU quilt process.
3) Neither user space nor kernel space can be distinguished.

Therefore, clock functions become meaningless in Linux.

2) test
Write the test1.c program and test the difference between the output using the clock function and the time program.

VI test1.c
# Include <stdio. h>
# Include <stdlib. h>
# Include <time. h>

Int main (void)
{
Long I = 1000l;
Clock_t start, finish;
Double duration;
Printf ("time to do % LD empty loops is", I );
Start = clock ();
While (-- I ){
System ("cd ");
}
Finish = clock ();
Duration = (double) (finish-Start)/clocks_per_sec;
Printf ("% F seconds", duration );
Return 0;
}

GCC test1.c-O test1

Time./test1
Time to do 1000 empty loops is 0.180000 seconds

Real 0m3. 492 s
User 0m0. 512 s
Sys 0m2. 972 s

3) summary:
(1) The program calls system ("cd"). Here, it mainly refers to the consumption of sub-processes in the system mode. The test1 program cannot reflect this.
(2) The second consumption of 0.180000 seconds is two clock () function calls divided by clocks_per_sec.
(3) The Clock () function returns a relative time instead of an absolute time.
(4) clocks_per_sec is a system-Defined Macro defined by the GNU standard library as 1000000.

 

2) times () Time Functions

1) Overview:

The prototype is as follows:
Clock_t times (struct TMS * BUF );

The TMS struct is as follows:
Strace TMS {
Clock_t tms_utime;
Clock_t tms_stime;
Clock_t tms_cutime;
Clock_t tms_cstime;
}

Note:
Tms_utime records the time when the process executes user code.
Tms_stime records the time when the process executes the kernel code.
Tms_cutime records the time when the sub-process executes the user code.
Tms_cstime records the time when the sub-process executes the kernel code.

2) test:

VI test2.c
# Include <sys/times. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <sys/types. h>
# Include <unistd. h>

Static void do_cmd (char *);
Static void pr_times (clock_t, struct TMS *, struct TMS *);

Int main (INT argc, char * argv []) {
Int I;
For (I = 1; argv [I]! = NULL; I ++ ){
Do_cmd (argv [I]);
}
Exit (1 );
}
Static void do_cmd (char * cmd ){
Struct TMS tmsstart, tmsend;
Clock_t start, end;
Int status;
If (START = times (& tmsstart) =-1)
Puts ("Times error ");
If (status = System (CMD) <0)
Puts ("system error ");
If (END = times (& tmsend) =-1)
Puts ("Times error ");
Pr_times (end-start, & tmsstart, & tmsend );
Exit (0 );
}
Static void pr_times (clock_t real, struct TMS * tmsstart, struct TMS * tmsend ){
Static long clktck = 0;
If (0 = clktck)
If (clktck = sysconf (_ SC _clk_tck) <0)
Puts ("sysconf Err ");
Printf ("real: % 7.2f", real/(double) clktck );
Printf ("user-CPU: % 7.2f", (tmsend-> tms_utime-tmsstart-> tms_utime)/(double) clktck );
Printf ("system-CPU: % 7.2f", (tmsend-> tms_stime-tmsstart-> tms_stime)/(double) clktck );
Printf ("child-user-CPU: % 7.2f", (tmsend-> tms_cutime-tmsstart-> tms_cutime)/(double) clktck );
Printf ("child-system-CPU: % 7.2f", (tmsend-> tms_cstime-tmsstart-> tms_cstime)/(double) clktck );
}

Compile:
GCC test2.c-O Test2

Test this program:
Time./Test2 "dd If =/dev/zero f =/dev/null BS = 1 m COUNT = 10000"
10000 + 0 records in
10000 + 0 records out
10485760000 bytes (10 Gb) Copied, 4.93028 S, 2.1 Gb/s
Real: 4.94
User-CPU: 0.00
System-CPU: 0.00
Child-user-CPU: 0.01
Child-system-CPU: 4.82

Real 0m4. 943 s
User 0m0. 016 s
Sys 0m4. 828 s

3) summary:
(1) through this test, the system's time program is basically the same as the Test2 program output.
(2) (double) clktck is obtained through clktck = sysconf (_ SC _clk_tck), that is, to obtain the time occupied by the user-CPU, use
(Tmsend-> tms_utime-tmsstart-> tms_utime)/(double) clktck );
(3) clock_t times (struct TMS * BUF); The returned value is the number of tick times in the past period.
(4) the return value of the Times () function is also a relative time.

 

3) Real-time function clock_gettiem

Added this function in posix1003.1. Its prototype is as follows:
Int clock_gettime (clockid_t clk_id, struct timespec * TP );

It has the following features:
1) It also has a time structure: timespec. The unit of timespec computing time is one thousandth of a second.
Strace timespec {
Time_t TV _sec;
Long TV _nsec;
}

2) clockid_t is used to determine the clock type.

Clock_realtime: Standard POSIX real-time clock
Clock_monotonic: POSIX clock, which runs at a constant rate. It does not reset or adjust, and its value is the same as clock_realtime.
Clock_process_cputime_id and clock_thread_cputime_id are implemented in the hardware timer of the CPU.

3) test:
# Include <time. h>
# Include <stdio. h>
# Include <stdlib. h>

# Define million 1000000

Int main (void)
{
Long int loop = 1000;
Struct timespec tpstart;
Struct timespec tpend;
Long timedif;

Clock_gettime (clock_monotonic, & tpstart );

While (-- loop ){
System ("cd ");
}

Clock_gettime (clock_monotonic, & tpend );
Timedif = million * (tpend. TV _sec-tpstart. TV _sec) + (tpend. TV _nsec-tpstart. TV _nsec)/1000;
Fprintf (stdout, "It took % LD microseconds", timedif );

Return 0;
}

Compile:
GCC test3.c-LRT-O test3

Computing Time:
Time./test3
It took 3463843 microseconds

Real 0m3. 467 s
User 0m0. 512 s
Sys 0m2. 936 s

 

4) gettimeofday ()

1) Overview:
Gettimeofday () can obtain the current system time, which is an absolute value.

The prototype is as follows:
Int gettimeofday (struct timeval * TV, struct timezone * tz)

The prototype of the timeval junction is as follows:
Struct timeval {
Time_t TV _sec;/* seconds */
Suseconds_t TV _usec;/* microseconds */
};

So it can be accurate to microseconds.

Test:
# Include <sys/time. h>
# Include <stdio. h>
# Include <unistd. h>
Int
Main (){
Int I = 10000000;
Struct timeval TVs, TVE;
Gettimeofday (& TVs, null );
While (-- I );
Gettimeofday (& TVE, null );
Double span = TVE. TV _sec-tvs. TV _sec + (TVE. TV _usec-tvs. TV _usec)/1000000.0;
Printf ("Time: %. 12f", span );
Return 0;
}

GCC test5.c
./A. Out
Time: 0.041239000000

 

5) Comparison of four time functions

1) Precision comparison:

There are various types of precision conversions:
1 second = 1000 milliseconds (MS), 1 millisecond = 1/1000 seconds (s );
1 second = 1000000 microseconds (μs), 1 microseconds = 1/1000000 seconds (s );
1 second = 1000000000 nanoseconds (NS), 1 nanoseconds = 1/1000000000 seconds (s );

2)
The Return Value of the clock () function is Millisecond (MS)
The Return Value of the Times () function is also Millisecond (MS)
The Return Value of the gettimofday () function is microsecond (μs)
The unit of measurement of the clock_gettime () function is one in, that is, the nanosecond (NS)

3) test the accuracy of the four functions:

VI test4.c

# Include <stdio. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <time. h>
# Include <sys/times. h>
# Include <sys/time. h>
# Define wait for (I = 0; I <298765432; I ++ );
# Define million 1000000
Int
Main (INT argc, char * argv [])
{
Int I;
Long TTT;
Clock_t S, E;
Struct tms aaa;

/* Use clock () function */
S = clock ();
Wait;
E = clock ();
Printf ("clock time: %. 12f", (e-S)/(double) clocks_per_sec );

/* Use times () function */
Long TPS = sysconf (_ SC _clk_tck );
S = times (& AAA );
Wait;
E = times (& AAA );
Printf ("times time: %. 12f", (e-S)/(double) TPS );

/* Use gettimeofday () function */
Struct timeval TVs, TVE;
Gettimeofday (& TVs, null );
Wait;
Gettimeofday (& TVE, null );
Double span = TVE. TV _sec-tvs. TV _sec + (TVE. TV _usec-tvs. TV _usec)/1000000.0;
Printf ("gettimeofday time: %. 12f", span );

/* Use clock_gettime () function */
Struct timespec tpstart;
Struct timespec tpend;

Clock_gettime (clock_realtime, & tpstart );
Wait;
Clock_gettime (clock_realtime, & tpend );
Double timedif = (tpend. TV _sec-tpstart. TV _sec) + (tpend. TV _nsec-tpstart. TV _nsec)/1000000000.0;
Printf ("clock_gettime time: %. 12f", timedif );

Return exit_success;
}

Gcc-LRT test4.c-O test4
Debian:/tmp #./test4
Clock Time: 1.190000000000
Time: 1.180000000000
Gettimeofday time: 1.186477000000
Clock_gettime: 1.179271718000

 

 

From: http://home.lupaworld.com/home.php? MoD = Space & uid = 56821 & Do = Blog & id = 138299

 

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.