测量程序运行的时间 测量CPU时钟频率
现在的系统基本都是多任务系统,一个时间段内有多个程序在运行。系统通过计时器中断来调
度各任务,一般是10ms调用一次。接下来介绍两种方法来计算单个进程的运行时间。
当进程运行时间相当长时(大于1s),可以直接调用clock()函数(ansi c)。
clock函数返回自进程开始到调用clock所用的clock tick。用clock返回值除以
CLOCKS_PER_SEC 常量,即得到进程所用的秒数。CLOCKS_PER_SEC在Windows是1000,
Linux中是1000 000。clock的实现是:系统在每次计时器中断时判断在执行哪个进程,然
后把那个进程的执行时间记录增加。
clock测量执行时间非常短的程序误差很大。对于测量执行时间非常短的程序的具体运行时
间,可以用INTEL 的RDTSC(Read Time Stamp Counter)指令,它是以时钟周期为单位
(1ns)的,比较精确,它把周期计数寄存器(64位无符号整数,每个时钟周期自动加1)中
的数据赋给edx、eax寄存器,其中edx存高32位,eax存低32位。我们在某段代码前求一次
周期计数器的值spot1,在此代码后面再求一次周期计数器的值spot2,spot2-spot1即得到
运行此代码的时钟周期数,然后转换成秒即可。
下面利用RDTSC测量系统的时钟频率:
#include <stdio.h>
#include <time.h>
#include <windows.h>//为了能调用Sleep()
int main(int argc, char **argv)
{int high0,low0,high1,low1,sleepTime;
double spot0,spot1;
sleepTime=10000;//ms,=10seconds
__asm
//是根据VS反汇编来写的,自己不会Assembly,但是程序运行结果是对的
{rdtsc mov dword ptr [high0],edx ;保存高32位到high0 mov
dword ptr [low0],eax ;保存低32位到low0 }
//Call Sleep function in Windows
Sleep(sleepTime);
__asm {rdtsc mov dword ptr [high1],edx ;同上
mov dword ptr [low1],eax }
spot0=(double)high0*(1<<30)*4+low0; //把两个32位合成浮点
spot1=(double)high1*(1<<30)*4+low1;
printf("%f4 GHz\r\n",(spot1-spot0)/(1e6*sleepTime)); //即输出时钟频率
return 0;}
结果会有点误差,正常情况下误差很小,我的CPU为1.8xxxGHz,测量也为1.8xxxGHz, 但
是某些运行会出现很奇怪的结果。
要想100%精确的测出一个进程的运行时间应该说是不可能的,不过误差可以很小(0.1%)。
参考:Computer Systems: A Programmer's Perspective,chapter 9
随机日志
1条评论 ▼