在探查器输出中线程并发开销时间的含义是什么?

时间:2011-02-09 08:05:12

标签: c++ c multithreading profiling

如果有英特尔VTune放大器经验丰富的人告诉我这件事,我将非常感激。

最近我收到了其他使用英特尔VTune Amplifier的人的性能分析报告。它告诉我,线程并发区域中存在高开销时间

开销时间的含义是什么?他们不知道(问我),我无法访问英特尔VTune放大器。

我的想法很模糊。这个程序有许多线程睡眠调用,因为pthread condition在目标平台中不稳定(或者我做得很糟糕)所以我改变了许多例程来在循环中工作,如下所示:

while (true)
{
   mutex.lock();
   if (event changed)
   {
      mutex.unlock();
      // do something
      break;
   }
   else
   {
      mutex.unlock();
      usleep(3 * 1000);
   }
}

这可以标记为开销时间

有什么建议吗?


我在英特尔网站上找到了有关开销时间的帮助文档。 http://software.intel.com/sites/products/documentation/hpc/amplifierxe/en-us/win/ug_docs/olh/common/overhead_time.html#overhead_time

摘录:

开销时间是一个持续时间,它从共享资源的发布开始,以收到该资源结束。理想情况下,开销时间的持续时间非常短,因为它减少了线程必须等待获取资源的时间。但是,并行应用程序中的所有CPU时间可能不会用于执行实际的工资负载工作。在并行运行时(英特尔®线程构建模块,OpenMP *)使用效率低的情况下,可能会在并行运行时内花费大量时间在高并发级别上浪费CPU时间。例如,这可能是由于递归并行算法中的低粒度工作分割造成的:当工作负载大小变得太低时,分割工作和执行内务工作的开销变得很大。

仍然令人困惑..这是否意味着“你做了不必要/太频繁的锁定”?

3 个答案:

答案 0 :(得分:2)

我也不是那么专家,尽管我自己尝试过使用pthread

为了证明我对开销时间的理解,让我们以一个简单的单线程程序为例来计算数组总和:

for(i=0;i<NUM;i++) {
    sum += array[i];
}

在该代码的一个简单[合理完成]多线程版本中,每个线程可以将数组分成一个部分,每个线程保持自己的总和,并且在完成线程之后,将总和相加。

在编写得非常糟糕的多线程版本中,数组可以像以前一样细分,每个线程都可以atomicAdd到全局总和。

在这种情况下,原子添加一次只能由一个线程完成。我相信开销时间是衡量所有其他线程在等待自己atomicAdd时花费的时间(您可以尝试编写此程序以检查是否要确定)。

当然,它还考虑了处理切换信号量和互斥量所需的时间。在你的情况下,它可能意味着在mutex.lock和mutex.unlock的内部花费了大量的时间。

我前一段时间(使用pthread_barrier)并行化了一个软件,并且遇到了运行障碍需要更长时间才能使用一个线程的问题。事实证明,必须有4个障碍的循环被迅速执行,以使开销不值得。

答案 1 :(得分:0)

抱歉,我不是pthread或英特尔VTune Amplifier的专家,但是,锁定互斥锁并将其解锁可能算作开销时间。

锁定和解锁互斥锁可以实现为系统调用,而分析器可能只是在线程开销之下。

答案 2 :(得分:0)

我不熟悉vTune,但在线程之间有一个OS开销切换。每次线程停止并且另一个加载处理器时,需要存储当前线程上下文,以便在线程下次运行时可以恢复它,然后需要恢复新线程的上下文,以便它可以继续处理。

问题可能是您有太多线程,因此处理器大部分时间都在它们之间切换。如果与处理器具有相同数量的线程,则多线程应用程序将最有效地运行。