0

我必须为 clock_gettime() 函数计时以估计和分析其他操作,这是家庭作业,所以我不能使用分析器,必须编写自己的代码。

我这样做的方式如下:

clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&begin);

for(int i=0;i<=n;i++)
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);

cout<<(end.tv_nsec-begin.tv_nsec)/n; //time per clock_gettime()

问题是当 n=100 时,输出为:370.63 ns,当 n=100000 时,输出:330 ns,当 n=1000000 时,输出:260 ns,n=10000000,输出:55 ns,......继续减少.

我知道这是因为指令缓存而发生的,但我不知道如何在分析中处理这个问题。因为例如,当我使用 gettime 估计函数调用的时间时,我怎么知道该 gettime 自己使用了多少时间?

取所有这些值的加权平均值是个好主意吗?(我可以运行我想要的相同次数的操作,取其加权平均值,减去 gettime 的加权平均值并获得对操作的良好估计,而不考虑缓存?)

欢迎任何建议。

先感谢您。

4

1 回答 1

0

计算时差时:(end.tv_nsec-begin.tv_nsec)/n

您只考虑经过时间的纳秒部分。您还必须考虑秒数,因为该tv_nsec字段仅反映秒的小数部分:

int64_t end_ns = ((int64_t)end.tv_sec * 1000000000) + end.tv_nsec;
int64_t begin_ns = ((int64_t)begin.tv_sec * 1000000000) + begin.tv_nsec;
int64_t elapsed_ns = end_ns - begin_ns;

实际上,使用您当前的代码,当纳秒部分end已经环绕并且小于纳秒部分时,您有时应该会得到负面结果begin

解决这个问题,您将能够观察到更一致的结果。


编辑:为了完整起见,这是我用于测试的代码,它得到了非常一致的结果(每次调用在 280 到 300ns 之间,无论我使用多少次迭代):

int main() {
  const int loops = 100000000;

  struct timespec begin;
  struct timespec end;
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &begin);

  for(int i = 0; i < loops; i++)
      clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);

  int64_t end_ns = ((int64_t)end.tv_sec * 1000000000) + end.tv_nsec;
  int64_t begin_ns = ((int64_t)begin.tv_sec * 1000000000) + begin.tv_nsec;
  int64_t elapsed_ns = end_ns - begin_ns;
  int64_t ns_per_call = elapsed_ns / loops;
  std::cout << ns_per_call << std::endl;
}
于 2013-10-19T18:13:00.520 回答