使用OpenMP的消费者 - 生产者模型

时间:2011-11-29 11:47:35

标签: model openmp consumer producer

我正在尝试使用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)对我没有帮助。我会尝试将它放在单独的函数中......

4 个答案:

答案 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)的嵌套并行性之前。