我有一个需要并行化的伪代码:
Post
do_work函数将基于i工作并写入输出以进行记录。现在,我想将此序列化实现转换为多线程实现;
我知道我可以做类似
的事情int thread_count=8;
for(int i=1;i<100000;i++)
{
do_work(i,record);
}
但是这将创建数千个会损害性能的线程。我相信发布的问题应该是最自然的形式,需要多线程,我想知道解决这个问题的标准c ++实践是什么......谢谢。
答案 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 ++编写了它的两个版本,如果你愿意,我很乐意分享。线程池是优化使用多核处理器资源的好方法。