• Unix/Linux环境C编程入门教程(22) C/C++如何获取程序的运行时间


    1.问:知道程序运行时间我们可以做什么?

    在《C++应用程序性能优化》一书中,如果大家读过相信大家一定对性能优化这一块非常上心,文中总是对优化前后的时间对比非常直观给我们一个感受。

    那么我们如何利用C语言提供的库函数获取一个应用程序的各阶段的运行效率,通过数据分析出该程序的瓶颈并且做出相应的优化。

    本文给大家讲解的clock()函数。

    2.我们首先看一看C/C++标准文档对于clock()函数的讲解

    3.函数原型 clock_t clock (void);

    函数返回值 clock()返回从"开启这个程序进程"到"程序中调用clock()函数"时之间的CPU时钟计时单元(clock tick)数

    Returns the processor time consumed by the program.
    返回程序所消耗的处理器时间

    4.两个重要的概念需要理解一下

    epoch:时间点。时间点在标准C/C++中是一个整数,它用此时的时间和标准时间点相差的秒数(即日历时间)来表示。
    通过时钟作为参考的划时代的系统有所不同,但它是关系到执行程序(通常它的发射)。要计算一个程序的实际处理时间,由时钟返回的值应比由以前调用同一个函数返回一个值。
    clock tick:时钟计时单元,一个时钟计时单元的时间长短是由CPU控制的。一个clock tick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位。


    5.clock函数

    The value returned is expressed in clock ticks, which are units of time of a constant but system-specific length (with a relation of CLOCKS_PER_SEC clock ticks per second).
    返回的值是以时钟计时单元为单位表示,这是一个恒定的但系统特定长度的时间单位(CLOCKS_PER_SEC表示每秒多少时钟计时单元)。
    The epoch used as reference by clock varies between systems, but it is related to the program execution (generally its launch). To calculate the actual processing time of a program, the value returned by clock shall be compared to a value returned by a previous call to the same function.

    时间点所参考的时钟的在不同系统间,它是关系到程序执行(通常它的启动)。要计算一个程序的实际处理器占用时间,由时钟返回的值应与以前调用同一个函数返回一个值相比。

    时间点

    Parameters

    参数

    none
    没有

    Return Value

    返回值

    The number of clock ticks elapsed since an epoch related to the particular program execution.

    On failure, the function returns a value of -1.
    如果失败,函数返回值是-1

    一句话这个函数的作用就是:

    启动这个程序程序中调用clock()函数时之间的CPU时钟计时单元(clock tick)的计数。

    举一个例子,调用clock的地方就像是我们在体育赛场上掐秒表的动作

    100m开跑计时员开始计时,第一个到达终点掐一下显示的时间是9.502s 第二个是9.559s

    9.502s9.559s都是从开始赛跑到终点的计时。这就好比我们的程序开始启动了,我们在一些容易造成性能瓶颈的地方前掐秒表----调用clock()函数一下,完了再掐一下秒表通过计算两次掐表的间隔来评估瓶颈的严重程度。

     

    6.讲讲clock_t
    clock_t is a type defined in <ctime> as an alias of a fundamental arithmetic type.

    clock_t是一个定义在ctime头文件中的类型 作为一个基本数据类型的别名。

    在C语言中clock_t定义的头文件就是time.h

    我们打开自己所在开发环境中的time.h 搜索一下clock_t便可以找到了

    如下显示

    从上如我们可以知道所谓的clock_t其实就是一个long型

    7.讲讲CLOCKS_PER_SEC

    前面我知道CLOCKS_PER_SEC是某一个特定的值

    进入time.h和查看clock_t的方法一样找到CLOCKS_PER_SEC

    显示如下

    可以看见CLOCKS_PER_SEC是一个宏 意味着在所有出现CLOCKS_PER_SEC的地方在编译的时候就会被替换成1000这个数值。

    8. 小试牛刀

    现在我们就试验一下 我通过编写3个函数testinit() testwork() testend()

    来模拟程序运行的一些模块的运行时间

    #include <stdio.h>      /* printf */
    #include <time.h>       /* clock_t, clock, CLOCKS_PER_SEC */
    #include <math.h>       /* sqrt */
    
    
    int testinit (int n)
    {
        int num = n * n;
        while(num)
        {
           --num;
        }
        return 0;
    }
    int testwork (int n)
    {
        printf ("Begin Calculating...
    ");
        int i,j;
        int freq=n-1;
        for (i=2; i<=n; ++i)
            for (j=sqrt(i);j>1;--j)
                if (i%j==0)
                {
                    --freq;
                    break;
                }
        return freq;
    }
    int testend (int n)
    {
        int num = n * n;
        while(num)
        {
           --num;
        }
        return 0;
    }
    int main ()
    {
      clock_t t;
      int f;
      //测试第一阶段 初始化
      printf ("Begin clock...
    ");
      t = clock();//第一个clock() t表示从程序启动到现在这个时刻的时间
      testinit(1500);
      t = clock() - t;//第二次调用clock()减去第一次获得的t的差值为两次掐表的间隔
      printf ("It took %d clicks (%f seconds) to call testinit().
    ",t,((float)t)/CLOCKS_PER_SEC);
    
      //测试第二阶段 工作
      //第一个clock() t表示从程序启动到现在这个时刻的时间
    t = clock(); 
      f = testwork(99999);
      //第二次调用clock()减去第一次获得的t的差值为两次掐表的间隔
      t = clock() - t;
      printf ("It took %d clicks (%f seconds)to call testwork().
    ",t,((float)t)/CLOCKS_PER_SEC);
      printf ("The number of primes lower than 100,000 is: %d
    ",f);
    
      //测试第三阶段
    
      //第一个clock() t表示从程序启动到现在这个时刻的时间
      t = clock();  testend(1255);
      //第二次调用clock()减去第一次获得的t的差值为两次掐表的间隔
      t = clock() - t;
      printf ("It took %d clicks (%f seconds)to call testend().
    ",t,((float)t)/CLOCKS_PER_SEC);
      return 0;
    }
    Output:

    通过比对数据我们分析出 testwork()函数耗时较大,很可能就是项目中的瓶颈。

    9.下面我们看看这个程序在各个平台的Unix/Linux运行如何呢?

    在RHEL7上

    在RHEL6上

    在Solaris上

    在MAC上

  • 相关阅读:
    转载 从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法
    TYVJ P1081 最近距离 Label:这不是分治!!!
    TYVJ P1086 Elevator Label:dp
    数字图像处理的三个层次
    栅格化是什么意思?
    图像基本知识
    修改了天空盒子但是点play还是没变原因
    地形编辑
    Bmp8位图像亮度如何调整?
    bmp图像作业笔记
  • 原文地址:https://www.cnblogs.com/new0801/p/6177090.html
Copyright © 2020-2023  润新知