用clock()函数计时的坑
程序中经常用time()函数来返回当前系统时间的秒数,来计时或计算时间差。如果需要用到更高精度的时间,就会自然想到用clock()函数。想当然的认为它返回从程序开始tick数,用clock()/CLOCKS_PER_SEC就能得到以秒计数的时间了。然而结果不是这样,看下面的程序log。一行开头是系统时间,后面是clock()算出来的,明显比系统时间要慢不少。
2019-03-06 17:47:55.865 16213-18332/ E/jniUtil-jni: cur_time 3.399163
2019-03-06 17:47:56.273 16213-18332/ E/jniUtil-jni: cur_time 3.671865
2019-03-06 17:47:56.722 16213-18332/ E/jniUtil-jni: cur_time 4.006435
2019-03-06 17:47:57.113 16213-18332/ E/jniUtil-jni: cur_time 4.277441
2019-03-06 17:47:57.527 16213-18332/ E/jniUtil-jni: cur_time 4.540576
2019-03-06 17:47:57.928 16213-18332/ E/jniUtil-jni: cur_time 4.775973
2019-03-06 17:47:58.269 16213-18332/ E/jniUtil-jni: cur_time 4.925488
2019-03-06 17:47:58.394 16213-18332/ E/jniUtil-jni: cur_time 4.989181
2019-03-06 17:47:58.488 16213-18332/ E/jniUtil-jni: cur_time 5.023780
2019-03-06 17:47:58.911 16213-18332/ E/jniUtil-jni: cur_time 5.222049
2019-03-06 17:47:59.480 16213-18332/ E/jniUtil-jni: cur_time 5.476535
2019-03-06 17:47:59.980 16213-18332/ E/jniUtil-jni: cur_time 5.724581
2019-03-06 17:48:00.551 16213-18332/ E/jniUtil-jni: cur_time 5.995964
2019-03-06 17:48:00.965 16213-18332/ E/jniUtil-jni: cur_time 6.183607
原因是clock()计算的是从程序运行开始被程序进程使用的CPU时间tick,而不是真正现实世界流逝的时间。很显然这个时间肯定要比现实时间要慢的多,除非CPU只有你这么一个进程在跑,占用了全部CPU。所以如果你要benchmark一段代码,看看运行这段代码花费了多少时间,用clock()很合适。那么要比较精确地计算现实流逝地时间,怎么办呢?用clock_gettime()。
extern int clock_gettime(clockid_t, struct timespec*);
struct timespec {
__kernel_time_t tv_sec;
long tv_nsec;
};
第一个参数clockid_t类型常见的有四种:
CLOCK_REALTIME:系统实时时间。
CLOCK_MONOTONIC:从系统启动时开始计时,不受系统时间被用户改变的影响。
CLOCK_PROCESS_CPUTIME_ID:本进程到当前代码系统CPU花费的时间,包含该进程下的所有线程。
CLOCK_THREAD_CPUTIME_ID:本线程到当前代码系统CPU花费的时间。
可以看到,如果用CLOCK_PROCESS_CPUTIME_ID,就和直接用clock()是一样的。而要计算现实时间,就不能用后两种类型,必须用CLOCK_REALTIME或者CLOCK_MONOTONIC。要计算时间差,秒对秒一减,纳秒对纳秒一减,统一到同一个单位相加即可。
除了上面四种clockid_t类型,还有几种。
CLOCK_REALTIME_COARSE,CLOCK_MONOTONIC_COARSE:带COARSE后缀的,精度没有不带后缀的高,但是速度快。
CLOCK_MONOTONIC_RAW:和CLOCK_MONOTONIC类似,但是它是访问的硬件时间,不受NTP时间服务器的调整和adjtime()的影响。
CLOCK_BOOTTIME:和CLOCK_MONOTONIC一样,但是包含系统挂起的时间。
用clock()函数计时的坑的更多相关文章
- Clock函数用法
clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t.在MSDN中,查得对clock函数定义如下: clock_t clock(void) ; 这个函数返回从“开启这个程序进程 ...
- clock函数返回负值~ (转)
使用clock() 函数来进行计时,时不时的返回一个很大的负数,怎么检查也检查不出错误,现在找出错误原因,给大家分享一下. 来源网页:http://kebe-jea.blogbus.com/logs/ ...
- times、 time、clock函数说明
sysconf( _SC_CLK_TCK ) 功能 获取系统的 时钟滴答的频率. clock_gettime() clock()返回的是各个线程运行cpu时间的和, 返回值一直都是0. 定义函数: ...
- C 语言 clock() 函数,例:计算多项式值
C 语言 clock() 函数,例:计算多项式值 /** * clock(): 捕捉从程序开始运行到 clock() 被调用时所耗费的时间. * 这个时间单位是 clock tick, 即" ...
- clock()函数的返回值精度问题
clock()函数返回值为1毫秒,就是0.001秒.clock函数功 能: 返回处理器调用某个进程或函数所花费的时间.用 法: clock_t clock(void);说明:clock_t其实就是lo ...
- CUDA-F-2-2-核函数计时
Abstract: 本文介绍CUDA核函数计时方法 Keywords: gettimeofday,nvprof 开篇废话 继续更新CUDA,同时概率和数学分析也在更新,欢迎大家访问www.face2a ...
- CUDA学习(二)之使用clock()函数
clock()函数是C/C++中的计时函数,相关的数据类型是clock_t,使用clock函数可以计算运行某一段程序所需的时间,如下所示程序计算从10000000逐渐减一直到0所需的时间. #incl ...
- 不要在Lua中使用os.clock()函数
1.os.clock函数的实现是调用了c语言的函数函数库,实现代码如下: static int os_clock (lua_State *L) { lua_pushnumber(L, ((lua_Nu ...
- C语言中clock函数的使用
#include<cstdio> #include<cstdlib> #include<ctime> using namespace std; int main() ...
随机推荐
- ASP.NET结合Redis实现分布式缓存
最近一个项目ASP.NET+MySQL 有的网页打开初始化的查询需要10秒甚至更久,用户体验极差,而且并发量变大的时候网站容易崩溃 后来想了两种解决方案都不是太满意 1.数据库里建一张缓存表,后台作业 ...
- linux搭建zabbix server
一.linux配置jdk 1.安装rpm包,安装完成位置:/usr/java/jdk1.8.0_152 2.配置环境变量/etc/profile: JAVA_HOME=/usr/java/jdk1.. ...
- vue环境项目启动后因为eslint语法限制报错
报错太多,截取了一部分. 解决方法找到项目根目录的build 找到webpack.base.conf.js 打开js文件找到下图的位置 再重新启动项目就好了
- (4)Linux常用基本操作
1.ping和traceroute 指定源IP ping:ping -I 源 目的 #I为大写的i 带源地址路由tracert:traceroute -d <目标地址> -s < ...
- 2018-2019-2 20165315《网络对抗技术》Exp2 后门原理与实践
2018-2019-2 20165315<网络对抗技术>Exp2 后门原理与实践 一.实验任务 使用netcat获取主机操作Shell,cron启动 使用socat获取主机操作Shell, ...
- MySQL主主
MySQL双主(主主)架构方案 在企业中,数据库高可用一直是企业的重中之重,中小企业很多都是使用mysql主从方案,一主多从,读写分离等,但是单主存在单点故障,从库切换成主库需要作改动.因此,如果 ...
- nohup python 没有print输出
nohup python -u crake.py >run.log 2>&1 &
- Zookeeper到底是干嘛的
在Zookeeper的官网上有这么一句话:ZooKeeper is a centralized service for maintaining configuration information, n ...
- linux服务配置
1,开机初始化的配置 iptables -F 清空防火墙 /etc/init.d/iptables stop #关闭iptables setenforce 0 #暂停selinux #编译安装py ...
- .net webapi 接收 xml 格式数据的三种情况
webapi 接收 xml 的三种方法 前段时间接到一个任务写一个小接口,要接收java端返回过来的短信xml数据. 刚拿到项目,我的第一想法是对方会以什么形式发送xml格式的数据给我呢,设想三种情况 ...