我正在尝试使用OpenMP实现单生产者 - 多用户模型(我知道我也可以选择可能更适合的boost线程。)
这是我的代码,它非常简单并且使用了线程感知队列类型:
bool producer_finished = false;
#pragma omp parallel default( none ) shared( producer_finished, buffer, datagen )
{
#pragma omp sections
{
#pragma omp section
{ // single producer
while( datagen ) {
DType data = datagen.next()
buffer.push( data );
}
producer_finished = true;
#pragma omp flush( producer_finished )
} // end omp section
#pragma omp section
{
#pragma omp for schedule( static, 1 )
for ( int i = 0; i < omp_get_max_threads() - 1; ++i ) {
while ( ! producer_finished ) {
#pragma omp critical( buffer )
{
DType = buffer.pop();
}
processData( data );
outputData( data );
#pragma omp flush( producer_finished )
}
} // end omp for
} // end omp section
} //end omp sections
} // end omp parallel
这里的问题是生产者启动并推送数据,直到缓冲区已满,但消费者永远不会启动。如果我删除“for pragma”周围的部分也会发生同样的情况。你能看出我的做法有什么不对吗?
我在编译期间也收到此警告:
warning: work-sharing region may not be closely nested inside of work-sharing, critical, ordered or master region
它指的是在该部分中嵌入for循环。在这种情况下,这样做的正确方法是什么?
感谢您的反馈。
编辑:刚刚找到this related question,set_omp_nested(1)对我没有帮助。我会尝试将它放在单独的函数中......
答案 0 :(得分:0)
OpenMP是为并行计算而设计的,它不是通用的线程库。因此,尝试使用OpenMP进行生产者/消费者循环只是使用错误的工具,恕我直言。
答案 1 :(得分:0)
您的OpenMP代码在语法上是错误的。 这就是编译器告诉你的。 并行部分和并行循环都是工作共享结构,它们可能不会彼此嵌套嵌套。 您可以在for构造周围添加一个内部并行循环,从而使用嵌套并行性,您可能需要明确地启用它。
此外,使用flush指令是不够的。 您还需要同步正在处理的数据。 我们强烈建议在没有列表的情况下使用flush - 如果有的话。
您可能希望向www.openmp.org上的论坛提出与OpenMp相关的问题,以便与OpenMP expers交谈。
最好的问候, 迪特
答案 2 :(得分:0)
请参阅OpenMP V3.0 specification附录A.21中正确使用flush
的示例。
答案 3 :(得分:0)
将整个#pragma omp解压缩为一个函数并将其更改为#pragma omg parallel for。
在执行当前的#pragma omp并激活与omp_set_nested(1)的嵌套并行性之前。