At present, there are various timing functions, the general processing is to call the timing function, write down the current time tstart, and then process a program, and then call the timing function, write down the processing time tend, then tend and tstart do poor, you can get the execution time of the program, However, the accuracy of various timing functions is different. Here are some simple records of the various timing functions.
Method 1, Time () gets the current system times, and the returned result is a time_t type, which is actually a large integer whose value is represented from cut (coordinated Universal time) January 1, 1970 00:0 0:00 (called the epoch Time of the UNIX system) the number of seconds to the current moment. header Files <time.h>
void Test1 () { time_t start,stop; Start = time (NULL); Foo ();//dosomething stop = time (NULL); printf ("Use time:%ld\n", (Stop-start));}
Method 2, the clock () function returns the number of CPU clock ticks (clock ticks) from "Open this program process" to "call clock () function in program", called Wall Clock Time in MSDN (Wal-clock)
Constant Clocks_per_sec, which is used to indicate how many clock ticks a second will have
void Test2 () { double dur; clock_t Start,end; start = Clock (); Foo ();//dosomething end = Clock (); Dur = (double) (end-start); printf ("Use time:%f\n", (Dur/clocks_per_sec));}
Method 3, the timeGetTime () function takes the system time in milliseconds. This is the time elapsed since the system was started, which is the Windows API
void Test3 () { DWORD t1,t2; T1 = timeGetTime (); Foo ();//dosomething t2 = timeGetTime (); printf ("Use time:%f\n", (T2-T1) *1.0/1000);}
Method 4, QueryPerformanceCounter () This function returns the value of the high-precision performance counter, which can be timed in subtle units. But QueryPerformanceCounter () The smallest unit of precise timing is the system-related, so the system must be queried to get the frequency of the beep that QueryPerformanceCounter () returns. QueryPerformanceFrequency () provides this frequency value to return the number of beeps per second. header Files <windows.h>
void Test4 () { large_integer t1,t2,tc; QueryPerformanceFrequency (&TC); QueryPerformanceCounter (&T1); Foo ();//dosomething QueryPerformanceCounter (&t2); printf ("Use time:%f\n", (T2). Quadpart-t1. QuadPart) *1.0/tc. QuadPart);}
Method 5, GetTickCount returns (retrieve) the number of milliseconds from the operating system boot to the current elapsed (elapsed), and its return value is DWORD
void Test5 () { DWORD t1,t2; T1 = GetTickCount (); Foo ();//dosomething t2 = GetTickCount (); printf ("Use time:%f\n", (T2-T1) *1.0/1000);}
Method 6, RDTSC instruction, in the Intel Pentium above level of CPU, there is a "timestamp (time Stamp)" part, which in the format of 64-bit unsigned integer number, recorded since the CPU power has elapsed since the number of clock cycles. Because the current CPU frequency is very high, so this component can achieve the nanosecond level of timing accuracy. This accuracy is unmatched by the above methods. In CPUs above Pentium, a machine instruction RDTSC (read time Stamp Counter) is provided to read the number of the timestamp and save it in the EDX:EAX register pair. Since the EDX:EAX register pair happens to be the register of the function return value of the C + + language in the Win32 platform, we can think of this instruction as a normal function call because RDTSC is not directly supported by the C + + inline assembler, so we need to use _ Emit pseudo-instruction directly embedded in the instruction of the machine code form 0x0f, 0X31
inline unsigned __int64 getcyclecount () { __asm { _emit 0x0F; _emit 0x31; }} void Test6 () { unsigned long t1,t2; T1 = (unsigned long) getcyclecount (); Foo ();//dosomething t2 = (unsigned long) getcyclecount (); printf ("Use time:%f\n", (T2-T1) *1.0/frequency); Frequency refers to the frequency of the CPU}
Method 7, Gettimeofday () The timing function in Linux, int gettimeofday (struct timeval * TV, struct timezone * tz), Gettimeofday () will The current time has the structure that the TV refers to returns, the local time zone information is put in the structure that TZ refers to.
The TIMEVAL structure is defined as: struct Timeval{long tv_sec;/* seconds */long tv_usec;/* MICROSECOND */};//timezone structure defined as: struct Timezone{int tz_ Minuteswest; /* and Greenwich TIME difference of how many minutes */int tz_dsttime; /* Daylight Saving Time status */};void test7 () { struct timeval t1,t2; Double Timeuse; Gettimeofday (&t1,null); Foo (); Gettimeofday (&t2,null); Timeuse = T2.tv_sec-t1.tv_sec + (t2.tv_usec-t1.tv_usec)/1000000.0; printf ("Use time:%f\n", timeuse);}
Method 8, the Linux environment, with the RDTSC instruction timing. Is the same as method 6. Just a little different in the way Linux is implemented.
#if defined (__i386__) static __inline__ unsigned long long getcyclecount (void) { unsigned long long int x; __asm__ volatile ("RDTSC": "=a" (x)); return x;} #elif defined (__x86_64__) static __inline__ unsigned long long getcyclecount (void) { unsigned hi,lo; __asm__ volatile ("RDTSC": "=a" (LO), "=d" (hi)); Return ((unsigned long) lo) | (((unsigned long) hi) <<32);} #endifvoid Test8 () { unsigned long t1,t2; T1 = (unsigned long) getcyclecount (); Foo ();//dosomething t2 = (unsigned long) getcyclecount (); printf ("Use time:%f\n", (T2-T1) *1.0/frequency); FREQUENCY CPU Frequency}
A simple comparison table is as follows
ordinal |
function |
type |
precision level |
|
1 |
time |
C system call |
low |
<1s | /tr>
2 |
clcok |
C system call |
low |
<10ms |
3 |
timegettime |
Windows API |
|
<1ms |
4 |
QueryPerformanceCounter |
Windows API |
high |
<0.1ms |
5 | Td>gettickcount
Windows API |
|
<1ms |
6 |
rdtsc |
directive |
High |
<0.1ms |
7 |
gettimeofday |
C system calls in Linux environment |
high |
<0.1ms |
In summary, the method 1,2,7,8 can be executed in the Linux environment, and the method 1,2,3,4,5,6 can be executed in the Windows environment. Where the return value type of timeGetTime () and GetTickCount () is DWORD, and when the number of statistics is too large, will result in 0, affecting the statistical results.
Test results, in the Windows environment, the main frequency is 1.6GHz, in units of seconds.
1 use time:02, use time:0.3900003, use, time:0.3880004 use, time:0.3947045 use, time:0.4070006 use time:0.398684
Linux environment, the main frequency is 2.67GHz, units in seconds
1 use Time:12 with time:0.2900007 use time:0.2884768 use time:0.297843
Because the time () timing function has a low precision, it will get different results when running the program multiple times, sometimes 0, or 1
The Foo () function is as follows:
void foo () { long I; for (i=0;i<100000000;i++) { long a= 0; A = a+1; }}
C + + Timing