首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >#杂注omp flush,线程间交换数据

#杂注omp flush,线程间交换数据
EN

Stack Overflow用户
提问于 2011-02-25 05:40:04
回答 1查看 5.3K关注 0票数 3

我写了一个关于如何使用omp flush在线程之间以生产者->消费者的方式交换数据的非常简单的例子,我发现了一个有趣的行为。

代码语言:javascript
复制
int a=-1;
int flag=1;
int count=0;
#pragma omp parallel  num_threads(2)
{ 
    int TID;
    TID=omp_get_thread_num();
#pragma omp sections 
    {

#pragma omp section /////////// Producer
        {

            for(int i=0; i<9;i++)
            {
                a=i;
#pragma omp flush(a)
                flag=1;
                printf("Producer a: %d  flag:%d  TID %d \n",a,flag,TID);

                while(flag)
                {

#pragma omp flush(flag)

                }

            }
            flag=2;
#pragma omp flush(flag)

        } // end producer

#pragma omp section  /////////// Consumer
        {
            while(1) {
                count++;

                flag=0;
                while(!flag)
                {
#pragma omp flush(flag)
                }
#pragma omp flush(a)
                printf("Consumer a: %d  Flag: %d  count %d TID %d \n",a,flag,count,TID);
                if (flag==2) break; // no more data

            } // end while(1)
        }// end consumer
    }// end sections

使用以下非常简单的代码将产生错误的输出: Producer a: 0 flag:1 TID 0

生产者a: 1标志:1 TID 0

消费者a: 1标志:1计数1 TID 1

生产者a: 2标志:1 TID 0

消费者a: 2标志:1计数2 TID 1

生产者a: 3标志:1 TID 0

消费者a: 3标志:1计数3 TID 1

生产者a: 4标志:1 TID 0

消费者a: 4标志:1计数4 TID 1

生产者a: 5标志:1 TID 0

消费者a: 5标志:1计数5 TID 1

生产者a: 6标志:1 TID 0

消费者a: 6标志:1计数6 TID 1

生产者a: 7标志:1 TID 0

消费者a: 7标志:1计数7 TID 1

生产者a: 8标志:1 TID 0

消费者a: 8标志:1计数8 TID 1

消费者a: 8标志:2计数9 TID 1

错误在于,消费者忽略了生成的第一个数据a=0。如果我简单地颠倒部分的顺序,让生产者成为线程1,那么一切都是好的……生产者a: 0标志:1 TID 1

消费者a: 0标志:1计数1 TID 0

生产者a: 1标志:1 TID 1

消费者a: 1标志:1计数2 TID 0

……我的错误是什么?

.在与Ejd进行了有趣的讨论之后(谢谢),代码被编辑为:

代码语言:javascript
复制
int a=-1;
int flag=0;
int count=0;
#pragma omp parallel  num_threads(2)
{ 
int TID;
TID=omp_get_thread_num();
#pragma omp sections 
{
#pragma omp section  /////////// Consumer
    {

        while(1) {
            count++;
            if (flag) printf("Consumer a: %d  Flag: %d  count %d TID %d \n",a,flag,count,TID);
            flag=0;
            while(!flag)
            {
#pragma omp flush(flag)
            }
            if (flag==2) break; // no more data

        } // end while(1)
    }// end consumer

#pragma omp section /////////// Producer
    {
        for(int i=0; i<9;i++)
        {
            a=i;
            printf("Producer a: %d  flag:%d  TID %d \n",a,flag,TID);
            flag=1;
            while(flag)
            {
#pragma omp flush(flag,a)
            }

        }
        flag=2;
#pragma omp flush(flag)

    } // end producer


}// end sections    

现在,它运行得很好。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-02-25 07:16:47

不幸的是,使用flush要比乍一看复杂得多。即使是OpenMP的专家也很难正确使用它。问题的一部分,是flush with a list定义得不好。基本上它是允许移动的,所以如果你有一个形式的序列:

代码语言:javascript
复制
a = ...
#pragma omp flush(a)
b = ...
#pragma omp flush(b)

转储清除( a )必须在a的设置之后,但是可以在设置之后移动并转储清除(B)。的下一次使用之前就必须发生。

在任何情况下,做你想做的事情的最好方法是使用不带列表的flush ,在你感兴趣的每一组变量之后刷新,在读取你感兴趣的每个变量之前做一次刷新。

另一个问题是您没有正确地传递。在消费者实际使用所产生的值之前,您不能在消费者中为生产者设置标志以生成另一个数字。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5110816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档