使用c ++线程/ boost线程的有效方法

时间:2015-08-20 05:09:04

标签: c++ multithreading boost

我有一个需要并行化的伪代码:

Post

do_work函数将基于i工作并写入输出以进行记录。现在,我想将此序列化实现转换为多线程实现;

我知道我可以做类似

的事情
int thread_count=8;
for(int i=1;i<100000;i++)
{
do_work(i,record);
}

但是这将创建数千个会损害性能的线程。我相信发布的问题应该是最自然的形式,需要多线程,我想知道解决这个问题的标准c ++实践是什么......谢谢。

4 个答案:

答案 0 :(得分:3)

创建多个线程有助于提高性能,因为每个线程可以在其自己的核心中运行,而不会影响另一个线程,因此您拥有的核心数量最多。但是你说他们do_work()函数写入记录。如果在这种情况下使用mutex在线程之间共享该变量,即使您在自己的内核上运行线程,也会严重降低性能。

在这种情况下,自旋锁可以帮助减少互斥锁的时间开销,但它仍然基于std::atomic_flag(在GNU g ++上编译时至少为boost::spinlock)这是一个原子变量,因此将需要同步缓存的开销。您应该只考虑将其并行化到每个线程可以在独立核心中运行的程度。

除非您的程序就像服务器,您需要在不阻止其他人的情况下提供请求。在这种情况下,线程池(可能会动态增长和收缩)应该是正确的选择。像Apache这样的服务器在很多情况下也使用线程池

答案 1 :(得分:2)

一种好的方法是使用并行算法,例如TBB parallel_for_each。它将为您创建一个(全局)线程池,并在所有可用CPU上安排工作/任务块,而无需超额订阅,例如:它不会创建比可用CPU更多的工作线程。

答案 2 :(得分:1)

您可以使用OpenMP吗?只需在循环之前添加(* Searches for a node with the given key in this BST and returns the result in the form of an option. Executes in O(lg n) time. *) type t<'K, 'V> = | Empty | Node of 'K * 'V * t<'K, 'V> * t<'K, 'V> let rec get k = function | Empty -> None | Node(k', v, l, r) -> if k < k' then get k l elif k > k' then get k r else Some(v) 并启用对编译器的openmp支持

答案 3 :(得分:1)

这是线程池的完美候选者。如果您不需要等待结果,简单的线程池就足够了。如果您需要等待结果并根据结果执行其他操作,则需要基于未来的池。为了我的工作,我用C ++编写了它的两个版本,如果你愿意,我很乐意分享。线程池是优化使用多核处理器资源的好方法。