real time、CPU time探讨
2017-11-15 18:06
375 查看
APUE 3.9节中关于系统调用read给出了不同大小的缓冲区会导致读取效率的差异。这里stevens用三种时间表示读取文件过程所花费的时间。这三种时间分别为真实/时钟时间(real / clock time),系统cpu时间(system
cpu time),用户cpu时间(user cpu time )。其意义如下:
真实时间:进程从开始执行到最后结束的时间,包括阻塞+就绪(排队等待)+运行的时间。也即我们能够真实感受到的时间。
系统cpu时间:进程运行时,在系统区执行的时间,如(write,read等系统调用),运行的地方位于系统内存中。
用户cpu时间:进程运行时,在用户区执行的时间。这里主要是我们自己编写的代码,运行在用户内存中。
程序从用户态到系统态需要消耗一定的时间,频繁的切换会导致系统运行的效率低下。但缓冲区又不宜太大,会浪费用户内存。所以合适的缓冲区大小很有必要。那我们如何确定一个最佳的缓冲区呢?stevens就用上面的三种时间去测试系统效率。他选用的bufsize从1,2,4,8
... 524888 这20个值进行测试,最后得出最佳大小。那我们如何获得这些时间呢?
其实linux提供了很多关于时间的系统调用,如time,gettimeofday,clock,times等等。其中前三个很常用,但无法获得system cpu time 和 user cpu time。所以这里主要介绍times函数。它的函数原型为:
[cpp] view
plain copy
#include<sys/times>
clock_t times(struct tms * buf);
struct 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 */
};
通过上面的介绍你会发现原来这个函数非常好用,只要在程序的末尾调用一下,就可以知道这个进程的system cpu time 和 user cpu time ,很方便吧,而返回值只要不等于(clock_t) -1,就说明返回成功。
[cpp] view
plain copy
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
#include<time.h>
#include<sys/times.h>
#include<sys/time.h>
#define BUF_SIZE 512
#define FILE_NAME "demo.txt"
#define err_exit(m) {perror(m); exit(1);}
int main(){
int i,fd,clocks_per_sec; //文件句柄和每秒时钟数
char buf[BUF_SIZE]; //文件缓冲区大小
struct tms st_tms; //times函数的机构
clock_t start = clock(); //记录起始时间,
fd = open(FILE_NAME, O_RDONLY | O_CREAT, 0664);
if(fd == -1) err_exit("open error");
while(read(fd, buf, BUF_SIZE) != 0);
for(i = 0; i < 1000000000; i++);
if (times(&st_tms) == -1) err_exit("times error");
clock_t end = clock();
clocks_per_sec = sysconf(_SC_CLK_TCK); //用于获得times函数的单位时钟数
printf("real times: %7dus\n", (end-start)/CLOCKS_PER_SEC*1000000);
printf("user times: %7dus\n", st_tms.tms_utime*1000000/(clocks_per_sec));
printf("syst times: %7dus\n", st_tms.tms_stime*1000000/(clocks_per_sec));
return 0;
}
上面的代码需要注意以下两点:
1.为了demo.txt文件足够大,方便看出系统态下的执行时间,可以用下面的语句生成:
dd if=/dev/zero of=demo.txt bs=1M count=512 --可以生成512M的文件,很方便的!
2.times和clock都有clock_t类型的变量,将它们转化为秒要分别除以system(_SC_CLK_TCK)和宏CLOCKS_PER_SEC,它们的值是不同的,具体可以man一下这两个函数。
讲到这里就把struct tms 的最后两个成员变量也讲一下吧,tms_cutime和tms_cstime是用来记录子进程(们)的system cpu time 和 user cpu time。他们的值是在父进程中执行wait 或 waitpid 时开始记录,等到wait返回后才停止记录。看如下代码:
[cpp] view
plain copy
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
#include<time.h>
#include<sys/times.h>
#include<sys/time.h>
#define BUF_SIZE 512
#define FILE_NAME "demo.txt"
#define err_exit(m) {perror(m); exit(1);}
int main(){
int i,fd,clocks_per_sec; //文件句柄和每秒时钟数
char buf[BUF_SIZE]; //文件缓冲区大小
struct tms st_tms; //times函数的机构
clock_t start = clock(); //记录起始时间,
fd = open(FILE_NAME, O_RDONLY | O_CREAT, 0664);
if(fd == -1) err_exit("open error");
while(read(fd, buf, BUF_SIZE) != 0);
for(i = 0; i < 1000000000; i++);
/* 产生子进程,并完成与父进程同样的操作,最后查看相应的时间值 */
int pid;
if((pid = fork()) < 0){
err_exit("fork error");
}else if(pid == 0){
int i = 0;
for( ; i < 1000000000; i++);
lseek(fd, 0, SEEK_SET); //重置读取位置,由于是复制父进程的,可能已到达文件末尾
while(read(fd, buf, BUF_SIZE) > 0);
exit(0); //子进程退出
}else{
wait(-1); //父进程等待子进程
}
if (times(&st_tms) == -1) err_exit("times error");
clock_t end = clock();
clocks_per_sec = sysconf(_SC_CLK_TCK); //用于获得times函数的单位时钟数
printf("real times: %7dus\n", (end-start)/CLOCKS_PER_SEC*1000000);
printf("user times: %7dus\n", st_tms.tms_utime*1000000/(clocks_per_sec));
printf("syst times: %7dus\n", st_tms.tms_stime*1000000/(clocks_per_sec));
printf("child user times: %7dus\n", st_tms.tms_cutime*1000000/(clocks_per_sec));
printf("child syst times: %7dus\n", st_tms.tms_cstime*1000000/(clocks_per_sec));
return 0;
}
注意:linux中clock函数并不能统计子进程(们)的时间哦,所以最后那个real time 只是父进程的时间,如果要统计可以使用time函数啦,time返回的时间点,所以当然足够精确啦!编译执行,看一下结果是否符合我们的预期值。
相关链接:https://stackoverflow.com/questions/17432502/how-can-i-measure-cpu-time-and-wall-clock-time-on-both-linux-windows#
cpu time),用户cpu时间(user cpu time )。其意义如下:
真实时间:进程从开始执行到最后结束的时间,包括阻塞+就绪(排队等待)+运行的时间。也即我们能够真实感受到的时间。
系统cpu时间:进程运行时,在系统区执行的时间,如(write,read等系统调用),运行的地方位于系统内存中。
用户cpu时间:进程运行时,在用户区执行的时间。这里主要是我们自己编写的代码,运行在用户内存中。
程序从用户态到系统态需要消耗一定的时间,频繁的切换会导致系统运行的效率低下。但缓冲区又不宜太大,会浪费用户内存。所以合适的缓冲区大小很有必要。那我们如何确定一个最佳的缓冲区呢?stevens就用上面的三种时间去测试系统效率。他选用的bufsize从1,2,4,8
... 524888 这20个值进行测试,最后得出最佳大小。那我们如何获得这些时间呢?
其实linux提供了很多关于时间的系统调用,如time,gettimeofday,clock,times等等。其中前三个很常用,但无法获得system cpu time 和 user cpu time。所以这里主要介绍times函数。它的函数原型为:
[cpp] view
plain copy
#include<sys/times>
clock_t times(struct tms * buf);
struct 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 */
};
通过上面的介绍你会发现原来这个函数非常好用,只要在程序的末尾调用一下,就可以知道这个进程的system cpu time 和 user cpu time ,很方便吧,而返回值只要不等于(clock_t) -1,就说明返回成功。
[cpp] view
plain copy
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
#include<time.h>
#include<sys/times.h>
#include<sys/time.h>
#define BUF_SIZE 512
#define FILE_NAME "demo.txt"
#define err_exit(m) {perror(m); exit(1);}
int main(){
int i,fd,clocks_per_sec; //文件句柄和每秒时钟数
char buf[BUF_SIZE]; //文件缓冲区大小
struct tms st_tms; //times函数的机构
clock_t start = clock(); //记录起始时间,
fd = open(FILE_NAME, O_RDONLY | O_CREAT, 0664);
if(fd == -1) err_exit("open error");
while(read(fd, buf, BUF_SIZE) != 0);
for(i = 0; i < 1000000000; i++);
if (times(&st_tms) == -1) err_exit("times error");
clock_t end = clock();
clocks_per_sec = sysconf(_SC_CLK_TCK); //用于获得times函数的单位时钟数
printf("real times: %7dus\n", (end-start)/CLOCKS_PER_SEC*1000000);
printf("user times: %7dus\n", st_tms.tms_utime*1000000/(clocks_per_sec));
printf("syst times: %7dus\n", st_tms.tms_stime*1000000/(clocks_per_sec));
return 0;
}
上面的代码需要注意以下两点:
1.为了demo.txt文件足够大,方便看出系统态下的执行时间,可以用下面的语句生成:
dd if=/dev/zero of=demo.txt bs=1M count=512 --可以生成512M的文件,很方便的!
2.times和clock都有clock_t类型的变量,将它们转化为秒要分别除以system(_SC_CLK_TCK)和宏CLOCKS_PER_SEC,它们的值是不同的,具体可以man一下这两个函数。
讲到这里就把struct tms 的最后两个成员变量也讲一下吧,tms_cutime和tms_cstime是用来记录子进程(们)的system cpu time 和 user cpu time。他们的值是在父进程中执行wait 或 waitpid 时开始记录,等到wait返回后才停止记录。看如下代码:
[cpp] view
plain copy
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
#include<time.h>
#include<sys/times.h>
#include<sys/time.h>
#define BUF_SIZE 512
#define FILE_NAME "demo.txt"
#define err_exit(m) {perror(m); exit(1);}
int main(){
int i,fd,clocks_per_sec; //文件句柄和每秒时钟数
char buf[BUF_SIZE]; //文件缓冲区大小
struct tms st_tms; //times函数的机构
clock_t start = clock(); //记录起始时间,
fd = open(FILE_NAME, O_RDONLY | O_CREAT, 0664);
if(fd == -1) err_exit("open error");
while(read(fd, buf, BUF_SIZE) != 0);
for(i = 0; i < 1000000000; i++);
/* 产生子进程,并完成与父进程同样的操作,最后查看相应的时间值 */
int pid;
if((pid = fork()) < 0){
err_exit("fork error");
}else if(pid == 0){
int i = 0;
for( ; i < 1000000000; i++);
lseek(fd, 0, SEEK_SET); //重置读取位置,由于是复制父进程的,可能已到达文件末尾
while(read(fd, buf, BUF_SIZE) > 0);
exit(0); //子进程退出
}else{
wait(-1); //父进程等待子进程
}
if (times(&st_tms) == -1) err_exit("times error");
clock_t end = clock();
clocks_per_sec = sysconf(_SC_CLK_TCK); //用于获得times函数的单位时钟数
printf("real times: %7dus\n", (end-start)/CLOCKS_PER_SEC*1000000);
printf("user times: %7dus\n", st_tms.tms_utime*1000000/(clocks_per_sec));
printf("syst times: %7dus\n", st_tms.tms_stime*1000000/(clocks_per_sec));
printf("child user times: %7dus\n", st_tms.tms_cutime*1000000/(clocks_per_sec));
printf("child syst times: %7dus\n", st_tms.tms_cstime*1000000/(clocks_per_sec));
return 0;
}
注意:linux中clock函数并不能统计子进程(们)的时间哦,所以最后那个real time 只是父进程的时间,如果要统计可以使用time函数啦,time返回的时间点,所以当然足够精确啦!编译执行,看一下结果是否符合我们的预期值。
相关链接:https://stackoverflow.com/questions/17432502/how-can-i-measure-cpu-time-and-wall-clock-time-on-both-linux-windows#
相关文章推荐
- 探讨linux进程的三种时间(real time, system cpu time, user cpu time)的实现
- simulation is not running in real time due to excessive cpu load
- 人脸检测--FaceBoxes: A CPU Real-time Face Detector with High Accuracy
- 1)实际时间(real time): 从command命令行开始执行到运行终止的消逝时间; 2)用户CPU时间(user CPU time): 命令执行完成花费的用户CPU时间,即命令在用户态中执行时间总和; 3)系统CPU时间(system CPU time): 命令执行完成花费的系统CPU时
- Volumetric 3D Mapping in Real-Time on a CPU
- PVANET: Deep but Lightweight Neural Networks for Real-time Object Detection
- Apparatus, system, and method for automatically minimizing real-time task latency and maximizing non-real time task throughput
- Oracle Golden Gate 系列十八 -- GG 多对一 real-time data warehousing 说明 与 示例
- 一个关于struct tm 和 time_t 的结构体的探讨(日历打印)。。。
- Oracle Database 11.2下DG下参数delay与realtime apply特性冲突
- Realtime Shadow Rendering Log
- 《Adaptive Background Mixture Models For Real Time Tracking》翻译(一)
- currentTimeMillis,elapsedRealtime,uptimeMillis三个时间的区别
- MS SQL2005 How to find the top 50 cpu execution time.
- Note of big data dummies:Looking at Real-Time and Non-Real-Time Requirements
- RFC2326 - Real Time Streaming Protocol (RTSP) 完整中英文对照版
- Realtime Integration of OpenSER and Asterisk
- In-Game HD Video Capture using Real-Time YUYV-DXT Compression
- real-Time Correlative Scan Matching
- 【Real-Time Rendering 3rd】其之二,渲染管线简结