• 统计程序运行时间的C++源代码


    目前,根本没有办法精确测量程序运行时间,但可用两类方法进行估测:一是基于计时器Timer,一是基于计数器Counter。
    一) 基于Timer的测量方法

    缺点:精度不够,不能用于程序运行持续时间小于100ms的测量

    优点:准确性不是十分依赖于系统负载,并且在执行时间大于1s的程序上,与理论值之间的误差很低
    方法:在程序开始时读取计时器的内容,在程序终止前再次读取Timer的内容。

    接口函数:
    (1)Unix/Linux
    clock_t times(struct tms *buf);
    //return value:系统自启动以来经过的时间滴答数,常数CLK_TCK表示每秒经过的时钟滴答数
    //parameter:一个指向tms结构的指针
    //使用该函数时要包含头文件

    (2)Win32
    DWORD GetTickCount(VOID)
    //return value:the number of milliseconds that have elapsed since the system was started.
    //使用时应包含

    //link阶段应链接 kernel32.lib

    (3)可平台移植的代码

    clock_t clock(void)
    //常数CLOCKS_PER_SEC保证将该函数返回的值格式化为秒
    //使用该函数时要包含头文件

    /////////////////////////////////////////// C++
    #include
    using namespace std;

    ///////////////////////////////////////////

    clock_t start, finish;
    double duration;

    start = clock();

    //type your tested code here

    finish = clock();
    duration = (double)(finish – start) / CLOCKS_PER_SEC;
    printf(“%f seconds\n”, duration);

    system(“pause”);//经典的程序暂停法

    二)基于Counter的测量方法
    缺点:只能用汇编语言读取,不能保证通用性,在系统负载很大的情况下,将极大的影响准确性
    优点:精度高,并且因为得到的是程序执行期间所经过的时钟周期数,所以可大致估算出在不同硬件平台上程序的执行时间
    方法:在IA32体系结构中,CPU内部有一个被称为“时间戳(TimeStamp)”的64位无符号数计数器,存储自cpu上电以来所经过的时钟周期数
    (1)WIN32

    有一个QueryPerformanceCouter函数读取的就是64位的计数器.
    (2)目前的compiler有的不支持RDTSC指令,如果在这种compiler下,可以利用__emit指令绕过compiler执行,应该在文件头加入:
    #define CPUID __asm __emit 0fh __asm __emit 0a2h
    #define RDTSC __asm __emit 0fh __asm __emit 031h
    微软的C/C++编译器从6.0版开始支持CPUID和RDTSC指令,所以可以直接在程序中嵌入汇编代码,下面是一个简单示例:

    #include
    int main()
    {
    unsigned int cycle,i;
    __asm
    {
    CPUID
    RDTSC
    mov cycle,eax
    }
    for(i=0;i<10000;i++)
    ;
    __asm
    {
    CPUID
    RDTSC
    sub eax,cycle
    mov cycle,eax
    }
    printf("the program duration cycle = %d\n",cycle);
    return 0;
    }

    由于基于counter的测量方法受影响的因素较多,主要是Context Switch和Instruction Cache的影响,所以高精度计时必须设法消除上述两种因素的影响,对Context Switch主要是采用在负载低的机器上多次计算求平均,而对Instruction Cache多采用提前载入需要测试代码段的Instruction,然后执行测量的方法.

    具体做法参见 Computer System: A programmer's perspective(Chapter 7)

    例子:
    1#include “time.h”
    2
    3// 时间变量与时间函数
    4clock_t tstart = 0;
    5
    6
    7void Settime()
    8 {
    9 tstart = clock();
    10}
    11
    12
    13double Gettime()
    14 {
    15 return (double)((double)clock() – (double)tstart)/(double)CLOCKS_PER_SEC;
    16}
    17
    18
    19
    20int main()
    21{
    22 Settime();//开始计时
    23 /**//****
    24 do something ****/
    25
    26 cout << "-->监视耗时 : ” ;
    27 cout << Gettime()<< endl ;
    28
    29 return 1;
    30}

    from:http://www.dakaren.com/index.php/archives/768.htm

  • 相关阅读:
    Android Sensor Test
    [转]Android重力感应开发
    nexus5 root教程
    C# split字符串 依据1个或多个空格
    leetcode
    [ffmpeg 扩展第三方库编译系列] 关于须要用到cmake 创建 mingw32编译环境问题
    JAVA网络爬虫WebCollector深度解析——爬虫内核
    Apache htaccess 重写假设文件存在!
    javascript --- 事件托付
    LeetCode——Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/lidabo/p/2850401.html
Copyright © 2020-2023  润新知