【问题标题】:C++ What is the best way to frequently pause and restart threads?C ++频繁暂停和重新启动线程的最佳方法是什么?
【发布时间】:2014-10-04 03:52:12
【问题描述】:

我有一个非常可并行化的任务,所以我想使用多个线程来加速我的程序。但是,它并不像创建线程并让它们运行那么简单。线程必须重复执行某个任务,中间有中断,即伪代码如下所示:

loop
  wake threads up
  calculate x using the threads
  pause threads
  calculate something else without the threads

这种情况发生得非常频繁,准确地说是每秒 60 次。这就是为什么每次创建新线程都太慢了。我尝试使用每个线程的状态变量(正在运行、已暂停、已停止)以及带有条件变量的类事件构造或轮询机制来解决此问题。

考虑到只有大约 5% 的时间花在关键部分中,这两者都只给了我大约两倍的速度,这并没有我想象的那么快。 (我的 CPU 提供 4 个内核 * 2 = 8 个超线程)

我想条件变量的问题是唤醒不是立即的,而是有一些延迟,这意味着浪费了运行时间。轮询方法稍微慢一些,因为我猜在线程暂停时执行的代码会更慢,因为线程仍在使用 CPU。

实现我的想法的最佳方式是什么?

【问题讨论】:

  • 这个问题听起来很适合线程池和基于任务的多线程。特别是如果多线程工作单元的计算时间差异很大。
  • 问题依旧:线程池如何实现?
  • 你应该看看thread pooling in c++11
  • 您是对整个程序计时还是只对线程部分计时?您需要在期望中考虑到Amdahl's law
  • @AndreasT Intel TBB 是一个不错的选择。

标签: c++ multithreading concurrency


【解决方案1】:

您可以使用英特尔 TBB。如果您的任务足够简单,您可以使用parallel_for 等简单算法之一。 (parallel_for 使用lambas 更容易:https://software.intel.com/en-us/blogs/2009/08/03/parallel_for-is-easier-with-lambdas-intel-threading-building-blocks

【讨论】:

  • 我尝试了 parallel_for_each,它比我自己的两个实现略快,但仍然没有我期望的那么快。我可能会再次查看代码,也许我监督了一个奇怪的瓶颈。
【解决方案2】:

如果您希望线程阻塞直到发生某些事情,您可以将std::mutex(其锁定由std::unique_lock<std::mutex> 持有)与std::condition_variable 配对。

您使用std::condition_variablewait 成员,将std::unique_lock<std::mutex> 传递给它,并在满足线程唤醒条件时返回true 的函子。当线程在std::condition_variable 上等待时,它放弃了锁。当条件满足时,在std::condition_variable 上调用notify_one(假设问题中的线程是选择通知的线程)或notify_all,它会唤醒,重新获取锁,检查条件,然后当/如果它为真时返回(仍然持有锁)。

【讨论】:

  • 我的问题是,除了您所描述的之外,是否有更好的(阅读“更快”)方法来实现这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
相关资源
最近更新 更多