【发布时间】:2011-02-18 19:18:40
【问题描述】:
编辑:在写完这篇解释每一个小细节的长篇文章后,我才发现我的问题......如果有人能给我一个很好的答案,说明我做错了什么,我怎么能得到以秒为单位的执行时间(使用小数点后 5 位左右的浮点数),我将其标记为已接受。提示:问题在于我如何解释 clock_getttime() 手册页。
嗨,
假设我有一个名为myOperation 的函数,我需要测量它的执行时间。为了测量它,我使用了clock_gettime(),因为在其中一个 cmets 中推荐了here。
我的老师建议我们测量它N 次,这样我们就可以获得最终报告的平均值、标准差和中值。他还建议我们执行myOperationM 次而不是一次。如果myOperation 是一个非常快的操作,那么测量它M 次可以让我们了解它所花费的“实时”;导致正在使用的时钟可能没有测量此类操作所需的精度。因此,执行myOperation 仅一次或M 次实际上取决于操作本身是否需要足够长的时间来满足我们使用的时钟精度。
我在处理 M 次执行时遇到了麻烦。增加M 会降低(很多)最终平均值。这对我来说没有意义。就是这样,从 A 点到 B 点平均需要 3 到 5 秒。但是从 A 点到 B 点再回到 A 点需要 5 次(这就是 10 次,因为 A 到 B 点与 B 点相同)到 A) 然后你测量它。除了除以 10,你得到的平均值应该与你从 A 点到 B 点的平均时间相同,也就是 3 到 5 秒。
这是我希望我的代码执行的操作,但它不起作用。如果我不断增加从 A 到 B 再返回 A 的次数,每次的平均值都会越来越低,这对我来说毫无意义。
足够的理论,这是我的代码:
#include <stdio.h>
#include <time.h>
#define MEASUREMENTS 1
#define OPERATIONS 1
typedef struct timespec TimeClock;
TimeClock diffTimeClock(TimeClock start, TimeClock end) {
TimeClock aux;
if((end.tv_nsec - start.tv_nsec) < 0) {
aux.tv_sec = end.tv_sec - start.tv_sec - 1;
aux.tv_nsec = 1E9 + end.tv_nsec - start.tv_nsec;
} else {
aux.tv_sec = end.tv_sec - start.tv_sec;
aux.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return aux;
}
int main(void) {
TimeClock sTime, eTime, dTime;
int i, j;
for(i = 0; i < MEASUREMENTS; i++) {
printf(" » MEASURE %02d\n", i+1);
clock_gettime(CLOCK_REALTIME, &sTime);
for(j = 0; j < OPERATIONS; j++) {
myOperation();
}
clock_gettime(CLOCK_REALTIME, &eTime);
dTime = diffTimeClock(sTime, eTime);
printf(" - NSEC (TOTAL): %ld\n", dTime.tv_nsec);
printf(" - NSEC (OP): %ld\n\n", dTime.tv_nsec / OPERATIONS);
}
return 0;
}
注意:上面的diffTimeClock函数来自这个blog post。我用myOperation() 替换了我的实际操作,因为发布我的实际功能没有任何意义,因为我必须发布长代码块,您可以轻松地编写myOperation() 任何您喜欢的代码,如果你愿意。
如您所见,OPERATIONS = 1 和结果是:
» MEASURE 01
- NSEC (TOTAL): 27456580
- NSEC (OP): 27456580
对于OPERATIONS = 100,结果是:
» MEASURE 01
- NSEC (TOTAL): 218929736
- NSEC (OP): 2189297
对于OPERATIONS = 1000,结果是:
» MEASURE 01
- NSEC (TOTAL): 862834890
- NSEC (OP): 862834
对于OPERATIONS = 10000,结果为:
» MEASURE 01
- NSEC (TOTAL): 574133641
- NSEC (OP): 57413
现在,我不是数学天才,实际上远非如此,但这对我来说没有任何意义。我已经和一个和我一起做这个项目的朋友讨论过这个问题,他也无法理解这些差异。我不明白为什么当我增加OPERATIONS 时价值越来越低。无论我执行多少次,操作本身都应该花费相同的时间(当然,平均而言,不是完全相同的时间)。
您可以告诉我,这实际上取决于操作本身、正在读取的数据以及某些数据可能已经在缓存中等等,但我认为这不是问题所在。在我的例子中,myOperation 正在从 CSV 文件中读取 5000 行文本,用; 分隔值并将这些值插入到数据结构中。对于每次迭代,我都会破坏数据结构并再次对其进行初始化。
现在我想起来了,我也认为clock_gettime() 测量时间有问题,也许我没有正确使用它。我的意思是,看看最后一个例子,OPERATIONS = 10000。总共花费了 574133641ns,大概是 0.5s;不可能,等了几分钟,我受不了看着屏幕等着去吃东西了。
【问题讨论】:
-
由于您要测量两个事件之间的挂钟时间,您应该使用
CLOCK_MONOTONIC而不是CLOCK_REALTIME- 如果系统时间更改,后者可以跳转,前者不受影响。跨度> -
是的,但为什么不让我手动操作,系统时间会发生变化?
-
因为像
ntpd这样的系统守护进程改变了它? (或者共享系统上的系统管理员?) -
好的,这在我的测试机器上不太可能发生。但你有你的意思。我只是使用 REALTIME 而不是 MONOTONIC,因为我读过一些机器(甚至一些 Linux 发行版)没有实现 MONOTONIC,我希望我的老师能够编译代码(以防他没有)。当然,如果是 Mac,
clock_gettime()甚至都不存在(反正不在我朋友的 Mac 上)。
标签: c time clock performance