1、前言
測試一個程序的執行時間,時間包括用戶CPU時間、系統CPU時間、時鍾時間。之前獲取之前時間都是在程序的main函數用time函數實現,這個只能粗略的計算程序的執行時間,不能准確的獲取其他時間。在看《APUE》時,書中有關程序時間測試程序,非常正規,提供這三個時間。如是,上網搜了一下,進行總結一下。
2、獲取方法
有兩種方法可以獲取,第一種是用time命令,time 進程。第二種是通過在程序中進行記錄,首先利用sysconf函數獲取時鍾滴答數,再用times獲取tms結構。
查看times函數,man 2 tms,得到tms結構定義和times函數聲明如下:
struct tms { clock_t tms_utime; /* user time */ clock_t tms_stime; /* system time */ clock_t tms_cutime; /* user time of children */ clock_t tms_cstime; /* system time of children */ };
#include <sys/times.h>
clock_t times(struct tms *buf);
注意:此處計算的時間是時鍾滴答數,需要除以系統時鍾滴答數,得出實際的秒數。
3、測試例子:
測試程序如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/times.h> 4 #include <unistd.h> 5 6 #define BUFFER_SIZE 4 * 1024 7 8 int main() 9 { 10 int sc_clk_tck; 11 sc_clk_tck = sysconf(_SC_CLK_TCK); 12 13 struct tms begin_tms, end_tms; 14 clock_t begin, end; 15 system("date"); 16 begin = times(&begin_tms); 17 sleep(2); 18 end = times(&end_tms); 19 20 printf("real time: %lf\n", (end - begin) / (double)sc_clk_tck); 21 printf("user time: %lf\n", 22 (end_tms.tms_utime - begin_tms.tms_utime) / (double)sc_clk_tck); 23 printf("sys time: %lf\n", 24 (end_tms.tms_stime - begin_tms.tms_stime) / (double)sc_clk_tck); 25 printf("child user time: %lf\n", 26 (end_tms.tms_cutime - begin_tms.tms_cutime) / (double)sc_clk_tck); 27 printf("child sys time: %lf\n", 28 (end_tms.tms_cstime - begin_tms.tms_cstime) / (double)sc_clk_tck); 29 return 0; 30 }
測試結果如下所示:
采用time命令,測試結果如下所示:
4、參考網址
http://www.01happy.com/linux-process-time/
http://www.01happy.com/c-get-process-time/
linux查看進程的時鍾時間、用戶CPU時間和系統CPU時間
在linux下進行編程時,可能會涉及度量進程的執行時間。linux下進程的時間值分三種:
- 時鍾時間(real time):指進程從開始執行到結束,實際執行的時間。
- 用戶CPU時間(user CPU time):指進程中執行用戶指令所用的時間,也包括子進程。
- 系統CPU時間(system CPU time):指為進程執行內核程序所經歷的時間,例如調用read和write內核方法時,消耗的時間就計入系統CPU時間。
在linux下,可以使用time命令來查看程序執行時這三種時間值的消耗。筆者寫了一個測試程序,來演示這一個過程:
#include <stdio.h>
int
main(
void
)
{
int
i;
while
(i <= 10E7) {
i++;
}
return
1;
}
程序非常簡單了,就不說明了,編譯成二進制文件a.out,使用time命令執行,在筆者的電腦上輸入如下信息:
$ time ./a.out real 0m0.349s user 0m0.340s sys 0m0.004s
其中real表示時鍾時間,user表示用戶CPU時間,sys表示系統CPU時間。time命令也可以用於系統的命令,如time ls、time ps等等。
C語言獲取時鍾時間、用戶CPU時間和系統CPU時間
C語言里可以通過times函數獲取這三種時間,times函數說明如下:
#include <sys/times.h>
clock_t
times(
struct
tms *buf);
參數tms的結構如下:
struct
tms {
clock_t
tms_utime;
/* user time */
clock_t
tms_stime;
/* system time */
clock_t
tms_cutime;
/* user time of children */
clock_t
tms_cstime;
/* system time of children */
};
其中時間都是以滴答數(clock tick)為單位,詳細可以用man 2 times查看幫助手冊。下面的示例用來計算執行系統命令date消耗的三種時間值。
#include <stdio.h>
#include <sys/times.h>
#include <unistd.h>
#include <stdlib.h>
int
main(
void
)
{
//獲取滴答數,在ubuntu 12.04下為100
int
clktck = 0;
if
((clktck = sysconf(_SC_CLK_TCK)) < 0) {
printf
(
"%s\n"
,
"sysconf error"
);
exit
(0);
}
struct
tms tmsstart, tmsend;
clock_t
start, end;
//獲取開始時間
if
((start = times(&tmsstart)) == -1) {
printf
(
"%s\n"
,
"times error"
);
exit
(0);
}
//執行系統函數date
system
(
"date"
);
//獲取結束時間
if
((end = times(&tmsend)) == -1) {
printf
(
"%s\n"
,
"times error"
);
exit
(0);
}
printf
(
"real: %7.2f\n"
, (end - start)/(
double
) clktck);
printf
(
"user: %7.2f\n"
,
(tmsend.tms_utime - tmsstart.tms_utime)/(
double
) clktck);
printf
(
"sys: %7.2f\n"
,
(tmsend.tms_stime - tmsstart.tms_stime)/(
double
) clktck);
printf
(
"child user: %7.2f\n"
,
(tmsend.tms_cutime - tmsstart.tms_cutime)/(
double
) clktck);
printf
(
"child sys: %7.2f\n"
,
(tmsend.tms_cstime - tmsstart.tms_cstime)/(
double
) clktck);
return
1;
}
編譯執行上面的程序,輸出如下:
$ ./a.out Sun Dec 9 12:50:39 CST 2012 real: 0.01 user: 0.00 sys: 0.00 child user: 0.00 child sys: 0.00
其中child user就是執行date命令消耗的用戶CPU時間,child sys就是執行date命令消耗的系統CPU時間。這里會發現這兩個值都為0,因為滴答數為100,只能精確到小數點后面兩位,date的執行時間非常快,所以就為0了。如何精確到小數點后面3位呢?