我有一个包含需要处理的元素的队列。我想并行处理这些元素。将是需要同步的每个元素的一些部分。在任何时间点都可以有最大 num_threads 运行线程。
我会提供模板,让您了解我想要实现的目标。
queue q
process_element(e)
{
lock()
some synchronized area
// a matrix access performed here so a spin lock would do
unlock()
...
unsynchronized area
...
if( condition )
{
new_element = generate_new_element()
q.push(new_element) // synchonized access to queue
}
}
process_queue()
{
while( elements in q ) // algorithm is finished condition
{
e = get_elem_from_queue(q) // synchronized access to queue
process_element(e)
}
}
我可以使用
我遇到的主要问题
我的计划是针对队列容器的intel tbb concurrent_queue。但是,我能使用pthreads函数(互斥,条件)吗?让我们假设这是有效的(它应该)。那么,我如何使用pthreads在一个时间点获得max num_threads?我想创建一次线程,然后,在一个元素进程之后,访问队列并获取下一个元素。然而,如果更复杂,因为我无法保证如果队列中没有元素,算法就完成了。
我的问题
在我开始实现之前,我想知道是否有一种简单的方法来使用intel tbb或pthreads来获得我想要的行为?更准确地说是并行处理队列中的元素
注意:我尝试过使用但没有成功。
答案 0 :(得分:1)
首先,pthreads为您提供了难以摆脱的便携性。您的问题似乎如下:让我们知道这些是不是真的,因为答案会改变: 1)您有一个运行代码的多核处理器 2)由于(1)
,您希望不超过 num_threads 个主题假设上述情况属实,以下方法可能适合您:
根据您在队列中添加/删除元素的频率,您可能希望使用比pthread_mutex _...更轻的重量来排队/取消元素。您可能希望使用更具机器特定的构造。
答案 1 :(得分:0)
TBB与其他线程包兼容。
TBB还强调可扩展性。因此,当您将程序移植到双核到四核时,您无需调整程序。通过数据并行编程,在添加处理器时,程序性能会提高(缩放)。
Cilk Plus也是另一个提供良好结果的运行时。
www.cilkplus.org
由于pThreads是一个低级别的主题库,你必须决定应用程序需要多少控制,因为它确实提供了灵活性,但在程序员工作量,调试时间和维护成本方面成本很高。
答案 2 :(得分:0)
我的建议是查看tbb::parallel_do
。它被设计为并行处理容器中的元素,即使容器本身不是并发的;即parallel_do
正确使用std::queue
而无需任何用户同步(当然,您仍然需要保护process_element()
内的矩阵访问权限。此外,使用parallel_do
您可以添加更多内容因为process_element()
创建并添加新元素到工作队列中,所以看起来就像你需要的那样工作(唯一的警告是新添加的工作将立即被处理,不像放入一个会推迟的队列处理所有“较旧”项目之后)。此外,您不必担心终止:parallel_do
将在处理完所有初始队列项目和新项目时自动完成。
但是,如果除了计算本身之外,工作队列可以同时从另一个源(例如来自I / O处理线程)馈送,那么parallel_do
是不合适的。在这种情况下,查看parallel_pipeline
或更好的TBB流程图可能是有意义的。
最后,应用程序可以使用TBB控制活动线程的数量,但这不是推荐的方法。