0

我正在尝试使用 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循环在section中的嵌套。在这种情况下,正确的方法是什么?

感谢您的反馈意见。

编辑:刚刚发现这个相关问题, set_omp_nested(1) 对我没有帮助。我会尝试将它放在单独的功能中......

4

4 回答 4

0

OpenMP 是为并行计算而设计的,它不是一个通用的线程库。因此,尝试使用 OpenMP 进行生产者/消费者循环只是使用了错误的工具,恕我直言。

于 2011-11-30T08:33:25.810 回答
0

请参阅OpenMP V3.0 规范附录 A.21flush中正确使用的示例。

于 2012-02-07T09:13:17.740 回答
0

您的 OpenMP 代码在语法上是错误的。这就是编译器告诉你的。并行部分和并行循环都是工作共享结构,它们可能不会立即相互嵌套。您可以在 for 构造周围添加一个内部并行循环,从而使用嵌套并行性,您可能需要明确启用它。

此外,使用 flush 指令是不够的。您还需要同步正在处理的数据。强烈建议在没有列表的情况下使用 flush - 如果有的话。

您可能想向 www.openmp.org 上的论坛提出 OpenMp 相关问题,以便与 OpenMP 专家交流。

最好的问候,迪特

于 2012-02-07T09:02:24.577 回答
0

将整个#pragma omp for 提取为一个函数并将其更改为#pragma omg parallel for。

在执行当前 #pragma omp parallel 之前,使用 omp_set_nested(1) 激活嵌套并行。

于 2017-11-06T13:54:48.297 回答