在C++中测量调用system()的执行时间

4
我在这里找到了一些测量执行时间的代码。 http://www.dreamincode.net/forums/index.php?showtopic=24685 然而,对于对system()的调用似乎不起作用。我想这是因为执行跳出了当前进程。
clock_t begin=clock();

system(something);

clock_t end=clock();
cout<<"Execution time: "<<diffclock(end,begin)<<" s."<<endl;

那么

double diffclock(clock_t clock1,clock_t clock2)
{
    double diffticks=clock1-clock2;
    double diffms=(diffticks)/(CLOCKS_PER_SEC);
    return diffms;
}

然而,这总是返回0秒...有没有其他方法可以工作?

此外,这是在Linux中。

编辑:还要补充的是,执行时间是几个小时的数量级。所以准确性并不是问题。

谢谢!


系统调用和对于system()函数的调用绝不是同一回事。我已经编辑并重新标记以反映这一点。 - anon
也许系统调用确实只需要0秒钟。你是故意尝试了一些长时间的操作吗? - Eli Bendersky
1
请注意,有两个函数可以测量:进程所花费的时间和实际占用的时间。getrusage 可以以微秒分辨率测量第一个。gettimeofday 可以以微秒分辨率测量第二个。如果您的进程休眠(等待输入...),getrusage 不会考虑到这一点,它也不会考虑其他进程所花费的时间。所以我猜如果任务是 I/O,您需要 gettimeofday,如果是 CPU 绑定,则需要 getrusage。不确定是否正确。 - Johannes Schaub - litb
谢谢!我会尝试这些并看看效果如何... - jm1234567890
此外,我正在测量的执行时间是以小时为单位的。 - jm1234567890
3个回答

10

你考虑过使用gettimeofday吗?

struct timeval tv;
struct timeval start_tv;

gettimeofday(&start_tv, NULL);

system(something);

double elapsed = 0.0;

gettimeofday(&tv, NULL);
elapsed = (tv.tv_sec - start_tv.tv_sec) +
  (tv.tv_usec - start_tv.tv_usec) / 1000000.0;

6

很不幸,Linux上的clock()只有一秒的分辨率(即使它以微秒为单位返回时间)。

许多人用gettimeofday()进行基准测试,但这只能测量经过的时间-而不是该进程/线程使用的时间-因此并不理想。显然,如果您的系统比较空闲,并且您的测试时间相当长,那么您可以平均结果。通常不是太大的问题,但仍值得知道的是,gettimeofday()返回的时间是非单调的-例如,当您的系统首次连接到NTP时间服务器时,它可能会有所波动。

用于基准测试的最佳工具是clock_gettime(),选择最适合您任务的选项。

  • CLOCK_THREAD_CPUTIME_ID-线程特定的CPU时间时钟。
  • CLOCK_PROCESS_CPUTIME_ID-来自CPU的高分辨率每进程计时器。
  • CLOCK_MONOTONIC-表示某个未指定起始点以来的单调时间。
  • CLOCK_REALTIME-系统范围的实时时钟。

注意:并非所有选项都支持所有Linux平台-除了等同于gettimeofday()的clock_gettime(CLOCK_REALTIME)。

有用的链接:使用clock_gettime对代码进行基准测试


0
Tuomas Pelkonen已经介绍了gettimeofday方法,可以获得微秒级别的时间。
在他的示例中,他继续将其转换为double。我个人已经将timeval结构体封装成我自己的类,将计数保持为整数的秒和微秒,并正确处理加减运算。
当我可以时,我更喜欢保持整数(具有精确的数学),而不是使用浮点数及其所有问题。

对于计时来说,准确性并不是非常重要的。大部分计时中的抖动水平意味着你可能只有几个有效数字(除非调用需要花费非常长的时间,这种情况下你可以使用手表计时)。 - Donal Fellows

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接