使用clock()评测C++线程

Profiling C++ threads with clock()

本文关键字:C++ 线程 评测 clock 使用      更新时间:2023-10-16

我正在尝试测量gcc线程在我的系统上的执行情况。我写了一些非常简单的测量代码,它是这样的。。。

start = clock();
for(int i=0; i < thread_iters; i++) {
  pthread_mutex_lock(dataMutex);
  data++;
  pthread_mutex_unlock(dataMutex);
}
end = clock();

我用CLOCKS_PER_SEC做通常的减法和div,得到100000000次迭代大约2秒的运行时间。然后,我稍微更改了分析代码,以便测量每个互斥锁/解锁调用的单独时间。

for(int i=0; i < thread_iters; i++) {
  start1 = clock();
  pthread_mutex_lock(dataMutex);
  end1 = clock();
  lock_time+=(end1-start1);
  data++;
  start2 = clock();
  pthread_mutex_unlock(dataMutex);
  end2 = clock();
  unlock_time+=(end2-start2)
}

相同迭代次数的次数是锁定:~27秒解锁:约27秒

我明白为什么程序的总时间会增加,循环中的计时器调用会更多。但是系统调用的时间加起来应该不到2秒。有人能帮我找出哪里出了问题吗?谢谢

clock调用还测量调用clock并从中返回所需的时间。这会在测量中引入偏差。也就是说,在clock函数的深处,它会获取一个样本。但是在运行代码之前,它必须从clock内部返回。然后,当您进行最终测量时,在可以进行时间采样之前,必须调用clock,并且控制必须经过该函数内部的某个地方,在那里它实际上获得了时间。因此,你将所有的开销都作为衡量的一部分。

您必须找出连续clock调用之间经过的时间(通过对多对clock调用进行一些采样以获得准确的平均值)。这会给你一个基线偏差:在两个时钟样本之间什么都不执行需要多少时间。然后你小心地从测量中减去你的偏差。

但是调用clock可能会干扰性能,因此无法得到准确的答案。调用内核以获取时钟会干扰一级缓存和指令缓存。对于像这样的细粒度测量,最好下降到内联汇编并从CPU读取循环计数寄存器。

clock最好用在第一个例子中:对执行多次迭代的东西进行采样,然后除以迭代次数来估计单个迭代时间。