由函数clock想到的
今天介绍一下clock这个函数的使用,它是C标准库的一部分,声明在头文件<time.h>中,返回处理器使用的时间值,函数声明为:
clock_t clock(void);
这个函数看起来很简单,但是当使用时还是有不少需要注意的地方,让我们先看看clock_t这个类型,它表示程序所占用的处理器时间,具体的实现可以是整形或者浮点型,例如我们如果查看codeblock12.11中的time.h文件,可以看到如下定义:
/*
* A type for measuring processor time (in clock ticks).
*/
#ifndef _CLOCK_T_DEFINED
typedef long clock_t;
#define _CLOCK_T_DEFINED
#endif
在这里,clock_t被定义为long类型,MS Visual Studio中的time.h与此完全相同,但是,如果你将其定义修改为double也没有什么不好的,虽然它的本意是指”ticks”,也就是中文中的“滴答”。那么什么是“滴答”呢?简单的将就是系统每发生一次时钟中断就会产生一个“滴答”,如果详细介绍的话,这设计很多系统内核时钟中断的问题,不过詹荣开老师在它的一篇文章《Linux内核的时钟中断》中对这些概念有着很详细透彻的解读,虽然文章发表于2003年,但其中的骨架知识仍然适用。
介绍完clock_t的概念,还要介绍一下CLOCKS_PER_SEC这个宏定义,(也是在time.h中),从它的字面意思就可得知,它指的是每秒的时钟滴答数,通过用clock函数返回值除以该值可以得到程序运行是实际秒数。CLOCKS_PER_SEC的实际值也是随着操作系统和编译器的差异而不同,例如现在Windows平台上的编译器通常会将其定义为1000,也就是说每秒会产生1000个时钟滴答数。而在一些比较古老的编译器中,比如说TC2.0中,该值是18.2个(当然,在TC2.0中不叫CLOCKS_PER_SEC,而叫CLK_TCK,但它们的实质是一样的,VC6.0中为了兼容保留了CLK_TCK的名称,但建议使用CLOCKS_PER_SEC),为什么不同的编译器的默认值差异这么大,这主要是因为与当时硬件条件有关,这是个历史问题,在这里就不继续探讨了。
另外,经常看到一些文章中把CLOCKS_PER_SEC翻译成每秒的时钟周期数,其实这是错误的,混淆了时钟周期(clock cycle)和时钟滴答(clock tick)的概念,关于这两个词的区别詹荣开老师也做了介绍。但如果你不想深挖,可以简单的认为要经过若干时钟周期才是一个时钟滴答,具体是多少个决定于系统中对可编程间隔定时器(Programmable Interval Timer,PIT)值的初始定义。
好了,说了这么多,让我们回到clock函数,它主要的用处是衡量我们程序时间开销,例如:
#include <time.h>
#include <stdio.h> int main(int argc,char* argv[])
{
clock_t clock_time,start_time,end_time;
long int count = 1000000000;
start_time = clock();
while(count--);
end_time = clock();
clock_time = end_time - start_time;
printf("The program runs %lf clocks\n",(double)clock_time);
printf("The program runs %lf s\n",(double)(clock_time/CLOCKS_PER_SEC));
return 0;
}
程序的运行结果为:
由于在我的机器上,CLOCKS_PER_SEC的值被定义为1000,所以从结果上看是没有问题的。但我们稍微修改一下程序,把初始的count值改为10000,看看结果有什么不同。
#include <time.h>
#include <stdio.h>
int main(int argc,char* argv[])
{
clock_t clock_time,start_time,end_time;
long int count = 10000;
start_time = clock();
while(count--);
end_time = clock();
clock_time = end_time - start_time;
printf("The program runs %lf clocks\n",(double)clock_time);
printf("The program runs %lf s\n",(double)(clock_time/CLOCKS_PER_SEC));
return 0;
}
运行结果如下:
咦,为什么变成了0,结合编译器为我们指出的运行时间并联系上面的程序,可以发现程序的问题出现在由于count值很小,计算机在不到一个滴答的时间内就完成了计算,又因为clock_t的默认类型是long型,所以会截断取整,所以结果会产生错误。问题根源找到了,那有没有什么解决办法呢?欢迎大家提出自己的见解。
参考文献:
The Standart C Library P.J.Plauger
由函数clock想到的的更多相关文章
- c中计时函数 clock()
#include<time.h> int main() { // ... .. // .... printf("Time used = %.2lf\n",(double ...
- 计时函数 clock() in c and c++
在MSDN中,查得对clock函数定义如下: clock_t clock(void) ; 返回该程序从启动到函数调用占用CPU的时间.这个函数返回从“开启这个程序进程”到“程序中调用clock()函数 ...
- 从new Function创建函数联想到MVC模式
我们知道任何一个自定义函数都是Function构造器的实例,所以我们可以通过new Function的方式来创建函数,使用语法很简单, new Function(形参1, 形参2, ..., 形参N, ...
- clock()、time()、clock_gettime()和gettimeofday()函数的用法和区别【转】
转自:http://www.cnblogs.com/krythur/archive/2013/02/25/2932647.html 转自http://blog.sina.com.cn/s/blog_7 ...
- clock()、time()、clock_gettime()和gettimeofday()函数的用法和区别
1. clock_gettime( ) 提供了纳秒的精确度 int clock_gettime(clockid_t clk_id, struct timespect *tp); clockid_t c ...
- CodeForces 670E Correct Bracket Sequence Editor(list和迭代器函数模拟)
E. Correct Bracket Sequence Editor time limit per test 2 seconds memory limit per test 256 megabytes ...
- 第二章,循环结构,输入输出,clock
计时 计时函数: clock() 返回目前为止运行的时间 注意要除以常数 CLOCKS_PER_SEC, 才能得到以秒为单位. 头文件 time.h 管道 在windows命令行下执行echo 20| ...
- day16匿名函数
匿名函数,好像也就是 lambda 表达式 先来看一段函数,返回 def func(n): return n * 3 print(func(5))15 用lambda表达式写: func = lamb ...
- MPI 计时器函数 MPI_Wtime()
▶ 计时器函数 MPI_Wtime() 以及头文件 timer.h 中的宏函数 GET_TIME(),类似 time.h 中函数 clock() 的用法.注意 函数 clock() 记录的是CPU时间 ...
随机推荐
- ADO.NET增删改-------跟查不一样
建立数据库 create database ren go use database go create table user ( code nvarchar(20) primary key,--编号 ...
- 深入javascript作用域链到闭包
我之前用过闭包,用过this,虽然很多时候知道是这么一回事,但是确实理解上还不够深入.再一次看javascript高级程序设计这本书时,发现一起很多疑难问题竟然都懂了,所以总结一下一些理解,难免有错, ...
- 正则表达式的使用(C++)
1.判断手机号是否合法 const regex phonepattern("^[1]+[3,5]+\\d{9}$"); const regex Mobilepatten(" ...
- Python3基础 type获取变量的类型
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- HTML系列(HTMl+CSS+JavaScript+Jquery)--un
HTML 指超文本标签语言. 点击查看更详细的HTML内容 包括:一.基本标签;二.常用标签;三.表单<form></form>;四.表格<table></t ...
- Android 程序打包和安装过程
APP程序打包与安装的流程: APP的安装过程:
- 高仿bootstrap的layout效果(一)
公司研发一个新的cms,为了减少以后的修改和尽可能大程度的满足客户对cms的灵活需求,我的经理安排我去做一个与bootstrap的layout差不多的效果,这叫什么,锻炼的时候来了,加油,这个急不得一 ...
- .bash_profile和.bashrc的区别,ubuntu下为.profile,没有.bash_profile
.bash_profile 开机自动加载,比如java的环境变量放在里面 .bashrc打开shell或终端就会加载该文件,比如起的别名或快捷方式放里面.alias设置就在其中. 还有一个.profi ...
- Change An Item Property Using Set_Item_Property In Oracle Forms
Set_Item_Property is used to change an object's settings at run time. Note that in some cases you ca ...
- ORA-01009: 必需的参数缺失
第一步:看看是否有参数没有配: 第二步:如果第一步没问题,那么请在英文半角下把sql语句重新写一遍 以上~