详解如何在C/C++中测量一个函数或功能的运行时间

 更新时间:2023年12月03日 09:31:34   作者:zhonguncle  
本文算是一个比较完整的关于在 C/C++ 中测量一个函数或者功能的总结,最后会演示三种方法的对比,文章通过代码示例给大家介绍的非常详细,需要的朋友可以参考下

最常用的clock()

最常用的测量方法是使用clock()来记录两个 CPU 时间点clock_t,然后做差。这个方法的好处在于非常简单易写,如下(第一行是为说明需要导入哪个库):

#include <time.h>
.....

	clock_t begin = clock();

    ...需要被测量的代码
    
    clock_t end = clock();
    int duration = (end - begin)/CLOCKS_PER_SEC;

需要注意 3 点:

  1. CLOCKS_PER_SEC在 macOS 上是 1000000,也就是说(end - begin)的单位是微秒,所以要除以CLOCKS_PER_SEC
  2. 不同平台的clock_t类型是不一样的,有些平台是整数型,有些是使用浮点型。如果是浮点型的话,CLOCKS_PER_SEC或许可以不用写,还是要看time.h的相关内容。
  3. 这个方法中的“clock”一词表示的是时钟频率,而不是时间。早期的计算机是固定频率的(现在的一些计算器或者单片机其实也是固定频率的),这个方法就是诞生于那个时间的。

这种方法最大的弊端就是它测量是 CPU 运行时间,准确的说是该进程使用 CPU 的时间。这就导致了对于非 CPU 密集型程序来说,这个结果可能不是那么精确。当然导致的最大的问题是并行计算程序得到的时间完全不对,而且不能简单地使用核心数计算得到正确的时间。

因为这个方法是将多个 CPU 的运行时间加在一起了,串行计算的程序完全没有问题,但是并行计算的话,CPU 使用率一般不会达到或接近核心数*100%,因为计算机上还有其他任务也需要 CPU。比如说如果串行计算的程序使用率一般在 99% 左右,获取时间为 30 秒,但是对于 6 核的设备上运行的并行计算程序的话,CPU 使用率达到 570% 就很不错了,获取的时间可能为 27 秒,而实际上只用了 5 秒。

这是我在使用 ISPC 编写并行计算程序的时候发现的,所以我想寻找到新的方案,于是我发现了下一个方法。

timespec

timespec是一个简单的日历时间或者时间流逝。通过使用日历时间可以解决上一节中无法测量并行程序的实际运行时间的问题。但是“简单”这点的表现为整数时间,也就是说最小的时间精度是秒,而不是上一种方法中的微秒,不过这对于复杂函数或程序的测试来说没啥问题,毕竟 30 分钟和 31 分钟的性能差距不过 3.22%。

方法如下(第一行是为说明需要导入哪个库):

#include <time.h>
	time_t begin = time(NULL);
	
	...需要被测量的代码
    
    time_t end = time(NULL);
    int duration = (end - begin);

可以看到比上一种还要简单。

但是对于一些小型的测试来说,这个方法又不太行,因为整数带来的误差太大了,比如说 0.6 秒是 1.8 秒性能的三倍,但是在整数上只为 2 倍甚至是 1 倍(为什么有这个“甚至”等会演示可以看到),所以还是需要一个更精确时间测量方法,这个方法不光要适应并行计算,还要有一定的精度。

clock_gettime()

clock_gettime()可以完美的符合要求,但是使用上有点复杂。

clock_gettime()是我从文档的下面发现的。一开始我找到的是gettimeofday(),然后我去看了一下 IEEE 标准的文档gettimeofday (opengroup.org),发现在“FUTURE DIRECTIONS(未来方向)”这一栏表示gettimeofday()可能未来会被废弃;在“APPLICATION USAGE(应用使用)”这一栏表示应用应该使用clock_gettime()而不是gettimeofday。这必须得使用clock_gettime()了。

clock_gettime()的复杂之处在于太精确了。先来看看使用方法(第一行是为说明需要导入哪个库):

#include <time.h>
	struct timespec start;
    clock_gettime(CLOCK_REALTIME, &start);
	
	...需要被测量的代码
    
    struct timespec end;
    clock_gettime(CLOCK_REALTIME, &end);
    
	double duration = (double)(end.tv_nsec-start.tv_nsec)/((double) 1e9) + (double)(end.tv_sec-start.tv_sec);

clock_gettime()的参数CLOCK_REALTIME表示系统层面的实时时间;这个地方还可以用CLOCK_MONOTONIC,这个值是从系统启动开始一直运行的,一直连续的不跳跃的(除非手动改了),这个要比CLOCK_REALTIME精度小一些,所以更快一些。

可以看到计算运行时间的代码,也就是时间差的表达式长了很多,是因为clock_gettime()获取的时间分为两部分:秒和纳秒(在某论坛上有人指出在曾经的 Mac OS X 上这里是微秒,不确定,不过现在也是纳秒了)。秒是int很简单的,但是纳秒用的是long int,这就涉及到转换的问题了。所以就需要分别计算两个部分,转换合成。

实际演示(三种方法的对比)

这里展示一段并行计算程序在三种测量时间方法下的对比,各位可以看看差别(可以推测出测试设备是 6C6T 的 CPU 哦):

可以看到有时差别还是挺大的。

以上就是详解如何在C/C++中测量一个函数或者功能的运行时间的详细内容,更多关于在C/C++中测量函数运行时间的资料请关注脚本之家其它相关文章!

相关文章

  • C++ OpenCV实现物体尺寸测量示例详解

    C++ OpenCV实现物体尺寸测量示例详解

    本文主要介绍了利用OpenCV对物体的尺寸进行测量,即先定位到待测物体的位置,然后测量物体的宽高。感兴趣的同学可以跟随小编一起学习学习
    2022-01-01
  • VSCode 使用 Code Runner 插件无法编译运行文件名带空格的文件问题

    VSCode 使用 Code Runner 插件无法编译运行文件名带空格的文件问题

    这篇文章主要介绍了VSCode 使用 Code Runner 插件无法编译运行文件名带空格的文件问题,本文通过图文实例相结合给大家介绍的非常详细,需要的朋友可以参考下
    2021-07-07
  • Visual Studio配置静态库详细步骤和关键配置项

    Visual Studio配置静态库详细步骤和关键配置项

    这篇文章主要介绍了Visual Studio配置静态库的详细步骤和关键配置项的相关资料,静态库是一系列预先编译好的目标文件(.o文件或.obj文件)的集合,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-12-12
  • C语言实现扫雷算法简易版

    C语言实现扫雷算法简易版

    这篇文章主要为大家详细介绍了C语言实现扫雷算法简易版,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C++设计模式之模板方法模式

    C++设计模式之模板方法模式

    这篇文章主要介绍了C++设计模式之模板方法模式,本文讲解了什么是模板方法模式、模板方法模式的UML类图、模板方法模式的使用场合等内容,需要的朋友可以参考下
    2014-10-10
  • Qt Widgets库的实现实例

    Qt Widgets库的实现实例

    QtWidgets 提供了丰富的控件和工具,适合开发传统桌面应用程序本文主要介绍了Qt Widgets库的实现实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • 用C语言来实现一个简单的虚拟机

    用C语言来实现一个简单的虚拟机

    这篇文章主要介绍了用C语言来实现一个简单的虚拟机,其中栈数组的部分非常值得学习,需要的朋友可以参考下
    2015-07-07
  • C语言实现扫雷项目

    C语言实现扫雷项目

    这篇文章主要为大家详细介绍了C语言实现扫雷项目,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 浅谈C++ 中的常见的动态内存问题

    浅谈C++ 中的常见的动态内存问题

    C++动态内存管理容易引发多种严重问题,包括内存泄漏、重复释放、释放后使用、new/delete不匹配、未初始化内存、越界访问和异常安全问题,下面就来介绍一下常见的问题,感兴趣的可以了解一下
    2026-01-01
  • C语言实现学籍管理系统课程设计

    C语言实现学籍管理系统课程设计

    这篇文章主要为大家详细介绍了C语言实现学籍管理系统课程设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07

最新评论