【问题标题】:Consumer-producer model with OpenMP使用 OpenMP 的消费者-生产者模型
【发布时间】:2012-01-08 18:12:06
【问题描述】:

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

感谢您的反馈。

编辑:刚刚发现this related question,set_omp_nested(1) 对我没有帮助。我会尝试将它放在单独的函数中...

【问题讨论】:

    标签: model openmp consumer producer


    【解决方案1】:

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

    【讨论】:

    • 好吧,这也是我的印象,我想我会使用boost线程来实现它。我只是想使用现有代码快速实现,因为我已经知道一些 OpenMP...(尽管应该可以使用 boost 部分/任务)
    【解决方案2】:

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

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

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

    最好的问候, 迪特

    【讨论】:

    • 谢谢,我使用 boost 线程实现了生产者-消费者模式,它就像一个魅力。对我来说,除非我必须将基本的串行代码与许多 for 循环并行化,否则 OpenMP 已经破产了。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-10
        • 2015-09-22
        相关资源
        最近更新 更多