41

我想测量我的 C++ 代码的运行时间。执行我的代码大约需要 12 个小时,我想在代码执行结束时编写这个时间。我怎样才能在我的代码中做到这一点?

操作系统:Linux

4

7 回答 7

85

如果您使用的是 C++11,则可以使用system_clock::now()

auto start = std::chrono::system_clock::now();

/* do some work */

auto end = std::chrono::system_clock::now();
auto elapsed = end - start;
std::cout << elapsed.count() << '\n';

您还可以指定用于表示持续时间的粒度:

// this constructs a duration object using milliseconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

// this constructs a duration object using seconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::seconds>(end - start);

如果您不能使用 C++11,请查看 Boost 中的chrono

使用这样一个标准库的最大好处是它们的可移植性非常高(例如,它们都可以在 Linux 和 Windows 中工作)。因此,如果您决定在之后移植您的应用程序,您无需太担心。

这些库也遵循现代 C++ 设计,而不是类似 C 的方法。

编辑:上面的例子可以用来测量挂钟时间。然而,这并不是衡量程序执行时间的唯一方法。首先,我们可以区分用户时间和系统时间:

  • 用户时间:程序在用户空间运行所花费的时间。
  • 系统时间:程序在系统(或内核)空间中运行所花费的时间。例如,当执行系统调用时,程序会进入内核空间。

根据目标,可能需要或不需要将系统时间视为程序执行时间的一部分。例如,如果目标只是衡量对用户代码的编译器优化,那么最好省略系统时间。另一方面,如果用户想确定系统调用是否是一个显着的开销,那么也有必要测量系统时间。

此外,由于大多数现代系统是分时的,不同的程序可能会竞争几个计算资源(例如,CPU)。在这种情况下,可以进行另一种区分:

  • 挂钟时间通过使用挂钟时间,程序的执行以与我们使用外部(挂钟)时钟相同的方式测量。这种方法不考虑程序之间的交互。
  • CPU 时间在这种情况下,我们只计算程序实际在 CPU 上运行的时间。如果一个程序 (P1) 与另一个程序 (P2) 共同调度,并且我们想要获取 P1 的 CPU 时间,则此方法不包括 P2 运行和 P1 等待 CPU 的时间(而不是挂钟时间方法)。

为了测量 CPU 时间,Boost包含一组额外的时钟

  • process_real_cpu_clock, 捕获当前进程花费的挂钟 CPU 时间。
  • process_user_cpu_clock, 捕获当前进程花费的用户 CPU 时间。
  • process_system_cpu_clock, 捕获当前进程花费的系统 CPU 时间。一个类似元组的类process_cpu_clock,它一起捕获真实的、用户 CPU 和系统 CPU 进程时间。
  • 一个thread_clock线程稳定时钟,给出当前线程所花费的时间(当平台支持时)。

不幸的是,C++11 没有这样的时钟。但是 Boost 是一个广泛使用的库,并且这些额外的时钟可能会在某个时候被合并到 C++1x 中。因此,如果您使用 Boost,那么当新的 C++ 标准添加它们时,您将做好准备。

最后,如果您想测量从命令行执行程序所需的时间(而不是在程序中添加一些代码),您可以查看time命令,正如@BЈовић 建议的那样。然而,这种方法不允许您测量程序的各个部分(例如,执行一个函数所花费的时间)。

于 2012-06-16T11:02:27.760 回答
45

在 C++11 中使用std::chrono::steady_clock而不是std::chrono::system_clock测量运行时间。原因是(引用system_clock的文档):

在大多数系统上,系统时间可以随时调整

而 stable_clock 是单调的,更适合测量间隔:

类 std::chrono::steady_clock 表示单调时钟。这个时钟的时间点不能随着物理时间的推移而减少。此时钟与挂钟时间无关,最适合测量间隔。

这是一个例子:

auto start = std::chrono::steady_clock::now();
// do something
auto finish = std::chrono::steady_clock::now();
double elapsed_seconds = std::chrono::duration_cast<
  std::chrono::duration<double> >(finish - start).count();

一个实用的小技巧:如果您正在测量运行时间并且想要报告秒数std::chrono::duration_cast<std::chrono::seconds>,那么您很少需要,因为它会为您提供整数秒数。要以秒为单位获取时间,double请使用上面的示例。

于 2013-09-08T15:19:48.337 回答
10

您可以使用时间来启动您的程序。当它结束时,它会打印有关程序运行的漂亮时间统计信息。配置要打印的内容很容易。默认情况下,它会打印执行程序所花费的用户和 CPU 时间。

编辑:请注意,代码中的每个度量都不正确,因为您的应用程序将被其他程序阻止,因此给您错误的值*

*通过错误的值,我的意思是很容易获得执行程序所花费的时间,但该时间会根据程序执行期间的 CPU 负载而有所不同。为了获得相对稳定的时间测量,不依赖于 CPU 负载,可以使用时间执行应用程序并将 CPU 作为测量结果。

于 2012-06-16T11:03:12.583 回答
8

我在我的一个项目中使用了这样的东西:

#include <sys/time.h>

struct timeval start, end;
gettimeofday(&start, NULL);
//Compute
gettimeofday(&end, NULL);
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
        + (end.tv_usec / 1000 - start.tv_usec / 1000);

这是毫秒,它适用于 C 和 C++。

于 2012-06-16T11:02:22.090 回答
4

如果你想用 printf() 打印测量的时间,你可以使用这个:

auto start = std::chrono::system_clock::now();
/* measured work */
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
printf("Time = %lld ms\n", static_cast<long long int>(elapsed.count()));
于 2019-08-20T07:55:37.923 回答
4

这是我使用的代码:

  const auto start = std::chrono::steady_clock::now();

  // Your code here.

  const auto end = std::chrono::steady_clock::now();
  std::chrono::duration<double> elapsed = end - start;
  std::cout << "Time in seconds: " << elapsed.count() << '\n';

你不想使用std::chrono::system_clock,因为它不是单调的!如果用户在您的代码中间更改时间,您的结果将是错误的——它甚至可能是负数。std::chrono::high_resolution_clock可能使用实现,std::chrono::system_clock所以我也不建议这样做。

此代码还避免了丑陋的演员表。

于 2019-04-02T16:48:33.800 回答
0

您还可以尝试一些自动启动和停止的计时器类,并收集有关在任何代码块中花费的平均、最大和最小时间以及调用次数的统计信息。这些 cxx-rtimer 类在GitHub上可用,并支持使用 std::chrono、clock_gettime() 或 boost::posix_time 作为后端时钟源。

使用这些计时器,您可以执行以下操作:

void timeCriticalFunction() {
    static rtimers::cxx11::DefaultTimer timer("expensive");
    auto scopedStartStop = timer.scopedStart();
    // Do something costly...
}

在程序完成时将计时统计信息写入 std::cerr。

于 2018-01-14T07:21:28.797 回答