首先,先看一下头文件所提供的接口:
// time_check.h
#pragma once
#ifndef _TIME_CHECK
#define _TIME_CHECK
class CJudge
{
private:
unsigned long long total;
unsigned long long last;
unsigned long long t1,t2;
int expected;
public:
CJudge();
void gottime(int n = -1);
unsigned long long get_total();
unsigned long long get_last();
};
#endif
很简单地,提供一个类,这个类的对象可以测试时间。有一个打点函数gottime和两个get函数。两个get函数分别获取上一个间隔段所记录的时间与总共所有的间隔段所记录的时间。而gettime函数在参数为1的时候记录开始时间,在参数为2的时候,记录终止时间并将间隔时间设置为last,且将间隔时间加到total里面。如果使用无参数形式的话自动默认如果上次记录的开始时间这次就记录终止时间,上次记录终止时间这次就记录开始时间。而差别在于用有参数的形式时当参数与预期不符(比如应该记录开始时间你却让其记录终止时间)时会报错。
具体的实现如下:
// time_check.cpp
#include<stdio.h>
#include"time_check.h"
CJudge::CJudge()
{
t1 = 0;
t2 = 0;
last = 0;
total = 0;
expected = 1;
}
void CJudge::gottime(int n)
{
if (n == -1)
n = expected;
if (n != expected)
printf("Oh, I don't like this style!\n");
unsigned t_h, t_l;
__asm
{
rdtsc
mov t_l, eax
mov t_h, edx
}
if (n == 1)
{
t1 = ((unsigned long long)t_h << 32) + t_l;
expected = 2;
}
else
{
t2 = ((unsigned long long)t_h << 32) + t_l;
expected = 1;
last = t2 - t1;
total += last;
}
}
unsigned long long CJudge::get_total()
{
return (unsigned long long)(long double(total) / 1700);
}
unsigned long long CJudge::get_last()
{
return (unsigned long long)(long double(last) / 1700);
}
这个程序中除以1700是因为我cpu主频是1.7GHz的,因为我没有找到可以直接获取cpu主频信息的c语言函数或者汇编指令。如果有谁发现了可以告诉我...%>_<%...大家在使用的时候可以将这个数值依据自己电脑的cpu主频进行调整。
优点上比time.h或者clock.h中的时间监测函数快并且精确。如果对精度要求更高的话可以在这个的基础上修改为要求一定要使用有参数形式的gottime并且不检查是否有错。这样可以避免分支结构导致的预判错误浪费的时间。用这个头文件可以查出一个程序段中主要用时的代码并帮助程序员有目的地对程序时间进行优化。