转自:http://blog.csdn.net/fz_ywj/article/details/8109368

C语言中常用计时方法总结

1. time()

头文件:time.h

函数原型:time_t time(time_t * timer)

功能:返回以格林尼治时间(GMT)为标准,从1970年1月1日00:00:00到现在的此时此刻所经过的秒数。

用time()函数结合其他函数(如:localtime、gmtime、asctime、ctime)可以获得当前系统时间或是标准时间。

用difftime函数可以计算两个time_t类型的时间的差值,可以用于计时。用difftime(t2,t1)要比t2-t1更准确,因为C标准中并没有规定time_t的单位一定是秒,而difftime会根据机器进行转换,更可靠。

用法:

time_t start,end;

start =time(NULL);//or time(&start);

//…calculating…

end =time(NULL);

printf("time=%d\n",difftime(end,start));

总结:C标准库中的函数,可移植性最好,性能也很稳定,但精度太低,只能精确到秒,对于一般的事件计时还算够用,而对运算时间的计时就明显不够用了。

2. clock()

头文件:time.h

函数原型:clock_t clock(void);

功能:该函数返回值是硬件滴答数,要换算成秒,需要除以CLK_TCK或者 CLK_TCKCLOCKS_PER_SEC。比如,在VC++6.0下,这两个量的值都是1000。

用法:

clock_t start,end;

start = clock();

//…calculating…

end = clock();

printf("time=%f\n",(double)end-start)/CLK_TCK);

总结:可以精确到毫秒,适合一般场合的使用。

3. timeGetTime()

WIN32API

头文件:Mmsystem.h  引用库: Winmm.lib

函数原型:DWORD timeGetTime(VOID);

功能:返回系统时间,以毫秒为单位。系统时间是从系统启动到调用函数时所经过的毫秒数。注意,这个值是32位的,会在0到2^32之间循环,约49.71天。

用法:

DWORDstart,end;

start= timeGetTime();

//…calculating…

end= timeGetTime();

printf("time=%d\n",end-start);

总结:该函数的时间精度是五毫秒或更大一些,这取决于机器的性能。可用timeBeginPeriod和timeEndPeriod函数提高timeGetTime函数的精度。如果使用了,连续调用timeGetTime函数,一系列返回值的差异由timeBeginPeriod和timeEndPeriod决定。

4. GetTickCount()

WIN32API

头文件:windows.h

函数原型:DWORD WINAPI GetTickCount(void);

功能:返回自设备启动后的毫秒数(不含系统暂停时间)。

用法:

DWORDstart,end;

start= GetTickCount();

//…calculating…

end= GetTickCount();

printf("time=%d\n",end-start);

总结:精确到毫秒。对于一般的实时控制,使用GetTickCount()函数就可以满足精度要求。

5. QueryPerformanceCounter()、QueryPerformanceFrequency()

WIN32API

头文件:windows.h

函数原型:BOOLQueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);

BOOLQueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

功能:前者获得的是CPU从开机以来执行的时钟周期数。后者用于获得你的机器一秒钟执行多少次,就是你的时钟周期。

补充:LARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构, 其具体用法根据编译器是否支持64位而定:

typedef union_LARGE_INTEGER

{

struct

{

DWORD LowPart ;

LONG HighPart;

};

LONGLONG QuadPart ;

}LARGE_INTEGER;

用法:

在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率,然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经历的精确时间。

LARGE_INTEGER  num;

longlong start,end,freq;

QueryPerformanceFrequency(&num);

freq=num.QuadPart;

QueryPerformanceCounter(&num);

start= num.QuadPart;

//…calculating…

QueryPerformanceCounter(&num);

end= num.QuadPart;

printf("time=%d\n",(end-start)*1000/freq);

总结:这种方法的定时误差不超过1微秒,精度与CPU等机器配置有关,一般认为精度为透微秒级。在Windows平台下进行高精度计时的时候可以考虑这种方法。

6. gettimeofday()

Linux C函数。

头文件:sys/time.h

函数原型:int gettimeofday(struct timeval *tv,struct timezone *tz);

说明:其参数tv是保存获取时间结果的结构体,参数tz用于保存时区结果(若不使用则传入NULL即可)。

timeval的定义为:

struct timeval {

long tv_sec; // 秒数

long tv_usec; //微秒数

}

可见该函数可用于在linux中获得微秒精度的时间。

用法:

struct timeval start,end;

gettimeofday(&start, NULL );

//…calculating…

gettimeofday(&end, NULL );

long timeuse =1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec;

printf("time=%f\n",timeuse /1000000.0);

总结:使用这种方式计时,精度可达微秒。经验证,在arm+linux的环境下此函数仍可使用。推荐。

7. RDTSC - 读取时间标签计数器

X86架构CPU汇编指令。

操作码:0F 31 指令:RDTSC

功能:将时间标签计数器读入 EDX:EAX寄存器中。

说明:在Pentium以上的CPU中,提供了一条机器指令RDTSC来读取这个时间戳的数字,并将其保存在EDX:EAX寄存器对中。由于EDX:EAX寄存器对恰好是Win32平台下C++语言保存函数返回值的寄存器,所以我们可以把这条指令看成是一个普通的函数调用:

inline unsigned long longGetCycleCount()

{

__asm RDTSC

}

如果编译器不允许直接用RDTSC的话,可以用_emit伪指令直接嵌入该指令的机器码形式0X0F、0X31:

inline unsigned long long GetCycleCount()

{

__asm _emit 0x0F

__asm _emit 0x31

}

计算时还需要将得到的数字除以CPU的主频(单位GHZ),就能得到纳秒级的时间了。暂时我还没找到好的获得机器主频的方法,Windows平台下可以考虑用QueryPerformanceFrequency()函数,但这样一来就没办法在Linux下使用此方法。后来我考虑配合sleep函数,获取1秒中的机器周期数的方法来得到CPU主频。如果哪位有更好的方法,还请多多请教。

#ifdef WIN32

#include

#else

#include

#endif

inline unsigned long long GetNTime()

{

__asm("RDTSC");

}

static double hz=0.0;

void init_timer()

{

longlong t1=GetNTime();

#ifdef WIN32

Sleep(1000);

#else

sleep(1);

#endif

longlong t=GetNTime()-t1;

hz=(double)t/1000000000;

printf("hz=%fGhz\n",hz);

}

long long u_timer(long long *t,int mode)

{

if(hz<0.001)

init_timer();

if(!mode)

{

*t=GetNTime();

return0;

}

longlong t1=GetNTime()-*t;

t1/=hz;

longlong ns=t1%1000;

longlong us=(t1/1000)%1000;

longlong ms=(t1/1000000)%1000;

longlong s=t1/1000000000;

printf("time=");

if(s!=0)

printf("%llds",s);

if(ms!=0)

printf("%lldms",ms);

if(us!=0)

printf("%lldus",us);

if(ns!=0)

printf("%lldns",ns);

printf("\n");

*t=GetNTime();

returnt1;

}

总结:这种方法精确到纳秒,但缺点是非常短时间的计时会不稳定。最近因为项目需要,我也找了一下ARM+Linux平台上可以用的计时方法,后来选择了gettimeofday()。不知道ARM+Linux平台上有没有类似RDTSC的这种指令。

c语言计时纳秒_C语言中常用计时方法总结相关推荐

  1. c语言计时纳秒_C代码中以纳秒为单位计算函数时间

    匿名用户 不管您如何处理这个问题,也不管您使用的是哪种类型的System/OS,您最多只能得到一个近似的答案,由于问题的性质,会有相当大的差异. 第二,你需要一个支持这种调用的系统.如果你使用QNX中 ...

  2. C语言中常用计时方法总结

    转自:http://blog.csdn.net/fz_ywj/article/details/8109368 C语言中常用计时方法总结 1. time() 头文件:time.h 函数原型:time_t ...

  3. c语言字符串加减_C语言中指针的介绍

    C语言中指针的介绍 指针是C语言中广泛使用的一种数据类型. 运用指针编程是C语言最主要的风格之一.利用指针变量可以表示各种数据结构:能很方便地使用数组和字符串: 并能象汇编语言一样处理内存地址,从而编 ...

  4. iOS开发中常用的方法

    iOS开发中常用的方法 系统弹窗: 过期方法: UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"确认报价" ...

  5. Cookie | Cookie的理论基础、Cookie中常用的方法

    目录 一:Cookie的理论基础 二:Cookie中常用的方法 一:Cookie的理论基础 (1)cookie怎么生成? ①session的实现原理中,每一个session对象都会关联一个sessio ...

  6. 数学建模中常用的方法

    数学建模中常用的方法:类比法.二分法.差分法.变分法.图论法.层次分析法.数据拟合法.回归分析法.数学规划(线性规划,非线性规划,整数规划,动态规划,目标规划).机理分析.排队方法.对策方法.决策方法 ...

  7. org.apache.commons.lang.StringUtils中常用的方法

    org.apache.commons.lang.StringUtils中常用的方法,这里主要列举String中没有,且比较有用的方法: 1. 检查字符串是否为空: static boolean isB ...

  8. 整理 .Net 2.0 下 WinForms中常用的方法(更新中...)

    using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; /**// ...

  9. 17.Java常用实用类之String类中常用的方法以及一般应用场景,final关键字

    文章目录 1.String类学习 1.1.什么是String类 1.2.String类中常用的方法 1.2.1. 构造方法 1.2.2.public int length() 1.2.3.public ...

最新文章

  1. 批量启动关闭MS SQL 2005服务BAT
  2. 【Gans入门】Pytorch实现Gans代码详解【70+代码】
  3. Ember入门指南——教程目录
  4. html5中加亮文本,html实现高亮关键字
  5. CodeForces - 1486C2 Guessing the Greatest (hard version)(二分+交互)
  6. 数据结构--散列表 Hash Table
  7. Zebra项目:分析、实施与测试
  8. 被限高消费后,王思聪又有新动作:新增对外投资...
  9. json最大长度限制_MongoDB参数限制和阀值
  10. Win10下安装Intel Visual Fortran2019具体步骤及初始调试过程。
  11. plsql 64连接32oracle,32位plsql developer连接64位oracle的方法
  12. javaweb基础:JSP第一篇 -----简单聊jsp是什么,其指令以及脚本使用
  13. 【读书】格鲁夫给经理人的第一课-管理杠杆率
  14. Unity3d 联通沃商店接入问题
  15. 11 风险管理 人人都是项目经理系列(第11/13篇)
  16. 前后端分离之图片上传服务端处理方法(亲测通过)
  17. 修改Linux的分辨率
  18. 【小白笔记】目标跟踪(Unveiling the Power of Deep Tracking)论文笔记
  19. 一个微型的操作系统内核 MiniOS
  20. 关于ie中使用a标签无法打开(预览)pdf问题

热门文章

  1. iOS 6.1完美越狱教程
  2. 信息学奥赛一本通 1399:甲流病人初筛 | OpenJudge NOI 1.12 03:甲流病人初筛
  3. Elasticsearch搜索
  4. K26 SOM从emmc启动linux
  5. python电脑攻击_python实现MAC洪水攻击
  6. Linux进行syn攻击的代码,Linux遭受SYN洪水攻击设置
  7. ACPI协议所定义的计算机电源的几种管理状态(S、G、C)
  8. linux 软路由 中文,Linux 软路由性能测试及分析-Go语言中文社区
  9. 10.Python——max()的用法
  10. 令人敬仰的游戏界十大幕后制作高手