C语言也用tic、toc计时

  前几天看到同学写matlab代码时,随手写上tic、toc就记录了时间,甚感震惊——居然计时函数可以如此简洁。
  一般写 C 程序测速时,需要先记录起始时间,然后在结束时再次记录时间,并输出时间差。算起来要3行代码才能完成一个计时任务。一般用起来倒也不算麻烦,但是在寻找程序热点的时候,每几行代码就加入一段冗长的计时代码,会非常的碍眼。
  在此诱惑之下,我写了一个简单的计时器,使用时只需在开始计时时写上“tic”,后面每个需要计时的节点写上“toc”,在需要的时候使用“tictoc(stdout);”就可以输出各部分的运行时间。输出的格式形如“line 12-15: 0.87”。
  经过简单的预判断,程序可以支持 Windows 和 Linux,一般自己写点小程序够用了。
  程序也有一些缺陷,比如只支持单文件,不能在并行的程序快内使用。另外如果需要获得更好的精度及效率,Windows 下应使用 QueryPerformanceCounter(),Linux 下应使用 clock_gettime(),替代 getTime() 的实现。

  P.S. 如果想知道程序的热点,使用 Intel Amplifier 是一个很好的选择,可以看精确到行的耗时,也可以查看程序的并行程度,有针对性地提高性能。在官网上可以下载并免费申请一个月的试用 license。

  代码如下,也可以访问 github 获取(https://github.com/licstar/util/blob/master/timer.h)。

#ifndef TIMER_H
#define TIMER_H

#ifdef __linux__
#include <sys/time.h>
#else
#include <time.h>
#endif
#include <stdio.h>

double getTime(){
#ifdef __linux__
	timeval tv;
	gettimeofday(&tv, 0);
	return tv.tv_sec + tv.tv_usec * 1e-6;
#else
	return 1.0 * clock() / CLOCKS_PER_SEC;
#endif
}

#define tic tic_f(__LINE__);
#define toc toc_f(__LINE__);

#define MAX_LINE 10000

double _timer[MAX_LINE] = {0};
int _fromLine[MAX_LINE] = {0};
int _lastLineNum = -1;
double _lastRdtsc = 0;

inline void tic_f(int line){
	_lastLineNum = line;
	_lastRdtsc = getTime();
}

inline void toc_f(int line){
	double t = getTime();
	_fromLine[line] = _lastLineNum;
	_timer[line] += t - _lastRdtsc;
	_lastLineNum = line;
	_lastRdtsc = t;
}

inline void tictoc(FILE *out){
	int i;
	for(i = 0; i < MAX_LINE; i++){
		if(_timer[i] != 0)
			fprintf(out, "line %d - %d: %.3f\n", _fromLine[i], i, _timer[i]);
	}
	fflush(out);
}

#endif

1 评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注