由函数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时间 ...
随机推荐
- Java动态代理 cglib
代理模式:为某些对象提供代理以实现对这个对象的访问. 对一个对象进行访问控制的原因是为了只有在我们确实需要这个对象时才对它进行创建和初始化. 一般包括以下组件: 被代理者接口:提供被代理者的访问途径. ...
- UVA 10341 Solve It 二分
题目大意:给6个系数,问是否存在X使得等式成立 思路:二分.... #include <stdio.h> #include <math.h> #define EEE 2.718 ...
- [UVa1210]Sum of Consecutive Prime Numbers(前缀和,打表)
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- 读写分离提高 SQL Server 并发性能
以下内容均非原创,仅作学习.分享!! 在 一些大型的网站或者应用中,单台的SQL Server 服务器可能难以支撑非常大的访问压力.很多人在这时候,第一个想到的就是一个解决性能问题的利器——负载均衡. ...
- 通过EasyUI Tree说明SQL GUID和自增列ID的使用场景
最新在开发中用到了EasyUI里面的Tree,通过API可以看到这个Tree的数据格式如下: 其中ID比较重要,API也说了,最开始我考虑到GUID比自增ID多占用了一些空间,所以采用的自增ID,测试 ...
- WebSphere MQ 入门指南
WebSphere MQ 入门指南这是一篇入门指南.我们从最基本的概念说起: 基础概念 对于MQ,我们需要知道4个名词:队列管理器.队列.消息.通道:对于编程设计人员,通常更关心消息和队列,对于维护管 ...
- STORM_0009_Lifecycle-of-a-topology/拓扑的生命周期
http://storm.apache.org/releases/1.0.1/Lifecycle-of-a-topology.html STORM拓扑的生命周期 本页的内容基于0.7.1代码,后来 ...
- yii-mail yii 发送邮件
参考网址:http://shoukii0721.iteye.com/blog/1576225 有很多时候我们需要给用户发送邮件,作留言,或者是激活邮件.等用途. 需要注意的是,设置发送的邮件得有SMT ...
- JZs3c2440学习笔记一
1.连线 串口线usb-com,USB下载线 2.驱动安装 USB-serial, dnw的sec s3c2410x test驱动安装(win7下安装方法搜索:百问网WIN7,64,dnw) 3.烧 ...
- 2013 Multi-University Training Contest 8
HDU-4676 Sum Of Gcd 题意:给定一个1-N的全排列序列,N<=20000,有Q组询问,Q<=20000,每组询问给出左右区间[l, r],问区间内的任意两个数的gcd之和 ...