现在的位置: 首页 > 综合 > 正文

C++ 精确计时

2018年03月16日 ⁄ 综合 ⁄ 共 2125字 ⁄ 字号 评论关闭
1.毫秒精确
#include   <time.h>
#include   <stdio.h>

#include   <conio.h>
int   main()
{
  clock_t   t_begin,t_end;
 
  //代码1开始计时
  t_begin=clock();
//

//你的程序段

//
  t_end=clock();
  printf( "代码所用的时间:%f毫秒/n ",(double)(t_end-t_begin));
getch();
return   0;
}

2.微秒精确
下列代码实现1微秒的精确定时:
              LARGE_INTEGER   litmp;  
              LONGLONG   QPart1,QPart2;
              double   dfMinus,   dfFreq,   dfTim;  
              QueryPerformanceFrequency(&litmp);
              dfFreq   =   (double)litmp.QuadPart;//   获得计数器的时钟频率
              QueryPerformanceCounter(&litmp);
              QPart1   =   litmp.QuadPart;//   获得初始值
              do
              {
                    QueryPerformanceCounter(&litmp);
                    QPart2   =   litmp.QuadPart;//获得中止值
                    dfMinus   =   (double)(QPart2-QPart1);
                    dfTim   =   dfMinus   /   dfFreq;//   获得对应的时间值,单位为秒
              }while(dfTim <0.000001);
其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关。

3.更精确
        在Pentium的指令系统中有一条指令可以获得CPU内部64位计数器的值,我们可以通过代码两次获取该计数器的值而获得程序或代码运行的时钟周期数,进而通过你的cpu的频率算出一个时钟周期的时间,从而算出程序运行的确切时间。

        我们通过指令TDSIC来获得cpu内部计数器的值,指令TDSIC返回值放在EDX:EAX中,其中EDX中存放64位寄存器中高32位的值,EAX存放第32位的值.

        下面看看实现的代码:

  //用汇编实现获取一段代码运行的时间  
#include <iostream>

using   namespace   std;

void   GetClockNumber   (long   high,   long   low);
void   GetRunTime();
 
int   main()
{              
 
  long   HighStart,LowStart,HighEnd,LowEnd;
  long   numhigh,numlow;
  //获取代码运行开始时cpu内部计数器的值
  __asm                            
  {
    RDTSC  
    mov   HighStart,   edx
    mov   LowStart,   eax
  }
  for(int   i=   0;   i <100000;   i++   )
  {
                          for(int   i=   0;   i <100000;   i++   )
            {
             
            }
  }
 

    //获取代码结束时cpu内部计数器的值,并减去初值
                __asm
  {
    RDTSC
    mov   HighEnd,   edx
    Mov   LowEnd,     eax
    ;获取两次计数器值得差
    sub   eax,     LowStart
    cmp         eax,     0               ;   如果低32的差为负则求返,因为第二次取得永远比第一次的大
    jg           L1
    neg           eax  
    jmp           L2
                        L1:   mov   numlow,     eax
                        L2:   sbb   edx,     HighStart
    mov   numhigh,   edx
   
  }
                //把两个计数器值之差放在一个64位的整形变量中
                //先把高32位左移32位放在64的整形变量中,然后再加上低32位
  __int64     timer   =(numhigh < <32)   +   numlow;
                  //输出代码段运行的时钟周期数
                  //以频率1.1Gcpu为例,如果换计算机把其中的1.1改乘其它即可,因为相信大家的cpu都应该在1G以上     ^_^  
  cout < <   (double)   (timer   /1.1/1000000000)   < <   endl;
  return   0;
}  

          这样通过一条简单的汇编指令就可以获得程序或一段代码的大概时间,不过并不能得到运行的确切时间,因为即使去掉中间的循环,程序也会有个运行时间,

因为在第一次取得计数器的值后,有两条汇编指令mov   HighStart,   edx               mov   LowStart,   eax这两条指令当然也有运行时间   ,当然你可以减去这两条指令的运行时间(在1.1G的机子上是3e-8s),这样会更精确一点。

抱歉!评论已关闭.