Multithreading OpenMP while循环内并行

Multithreading OpenMP while循环内并行,multithreading,openmp,Multithreading,Openmp,// 编辑:如何使5个线程同时运行代码A和第6个线程同时运行代码B,然后在所有线程都有代码后将结果传递到单个线程中?我读到我不允许使用关键字屏障 这是我的原始代码 omp_set_num_threads(6); #pragma omp parallel { int TID = omp_get_thread_num(); while (true) { if (TID < 5) {

//

编辑:如何使5个线程同时运行代码A和第6个线程同时运行代码B,然后在所有线程都有代码后将结果传递到单个线程中?我读到我不允许使用关键字屏障

这是我的原始代码

omp_set_num_threads(6);
#pragma omp parallel
    {
        int TID = omp_get_thread_num();

        while (true)
        {
            if (TID < 5)
            {
                // codeA

            }

            else
            {
                // codeB
            }

            // combine result from A and B
            #pragma single
            {
                //show result A and B
            }
        }
    }
omp\u set\u num\u线程(6);
#pragma-omp并行
{
int TID=omp_get_thread_num();
while(true)
{
如果(TID<5)
{
//法典
}
其他的
{
//法典
}
//合并A和B的结果
#布拉格单曲
{
//显示结果A和B
}
}
}
在谷歌搜索足够多之后,我可能已经找到了一个解决方案


我应该能够设置5个线程来执行任务A,1个线程来执行任务B。我只需要在退出5个线程之前使用critical来累积结果。

以下代码是否举例说明了您想要实现的功能?在这种特殊情况下,线程0-4只需将其线程标识符加1累加到
Aresult
(由于它是一个共享变量,我们需要对它进行原子访问),而线程5只需将其线程标识符分配到
Bresult
#include <omp.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int Aresult = 0;
    int Bresult = 0;

    omp_set_num_threads(6);
    #pragma omp parallel
    {
        int TID = omp_get_thread_num();

        while (1 == 1)
        {
            if (TID < 5)
            {
                // codeA
                #pragma omp atomic
                Aresult += TID + 1; // Aresult should be 1+2+3+4+5
            }
            else
            {
                // codeB
                Bresult = TID;
            }

            #pragma omp barrier

            // combine result from A and B
            #pragma omp single
            {
                //show result A and B
                printf ("Aresult = %d Bresult = %d\n", Aresult, Bresult);

                // set Aresult & Bresult to 0 for next iteration
                Aresult = Bresult = 0;
            }

            #pragma omp barrier
        }
    }

}
顺便说一句:您错过了
#pragma omp single
中的omp

请注意,我在显示a和B的结果之间添加了两个
#pragma omp barrier
,以防止线程更改在Aresult/Bresult中计算的值。如果我们不添加屏障,并且任何未通过
#pragma omp single
的线程开始下一次迭代,则可能会发生这种情况

请注意,添加障碍是可能的,因为这是美国公认的答案

从OpenMP V3.0/第2.5节工作共享结构:

以下限制适用于工作共享构件:

团队中的所有线程都必须遇到每个工作共享区域 或者根本没有。工作共享区域和屏障的顺序 对于团队中的每个线程,遇到的区域必须相同

在这种情况下,每个线程在输入显示结果的代码之前和之后都会遇到障碍

#include <omp.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int Aresult = 0;
    int Bresult = 0;

    omp_set_num_threads(6);
    #pragma omp parallel
    {
        int TID = omp_get_thread_num();

        while (1 == 1)
        {
            if (TID < 5)
            {
                // codeA
                #pragma omp atomic
                Aresult += TID + 1; // Aresult should be 1+2+3+4+5
            }
            else
            {
                // codeB
                Bresult = TID;
            }

            #pragma omp barrier

            // combine result from A and B
            #pragma omp single
            {
                //show result A and B
                printf ("Aresult = %d Bresult = %d\n", Aresult, Bresult);

                // set Aresult & Bresult to 0 for next iteration
                Aresult = Bresult = 0;
            }

            #pragma omp barrier
        }
    }

}
#包括
#包括
int main(int argc,char*argv[])
{
int Aresult=0;
int-Bresult=0;
omp_设置_数量_线程(6);
#pragma-omp并行
{
int TID=omp_get_thread_num();
而(1==1)
{
如果(TID<5)
{
//法典
#布拉格omp原子
Aresult+=TID+1;//Aresult应该是1+2+3+4+5
}
其他的
{
//法典
Bresult=TID;
}
#布拉格奥姆普屏障
//合并A和B的结果
#布拉格omp单曲
{
//显示结果A和B
printf(“Aresult=%d Bresult=%d\n”,Aresult,Bresult);
//为下一次迭代将Aresult&Bresult设置为0
Aresult=Bresult=0;
}
#布拉格奥姆普屏障
}
}
}

以下代码是否举例说明了您想要实现的功能?在这种特殊情况下,线程0-4只需将其线程标识符加1累加到
Aresult
(由于它是一个共享变量,我们需要对它进行原子访问),而线程5只需将其线程标识符分配到
Bresult
。 顺便说一句:您错过了
#pragma omp single
中的omp

请注意,我在显示a和B的结果之间添加了两个
#pragma omp barrier
,以防止线程更改在Aresult/Bresult中计算的值。如果我们不添加屏障,并且任何未通过
#pragma omp single
的线程开始下一次迭代,则可能会发生这种情况

请注意,添加障碍是可能的,因为这是美国公认的答案

从OpenMP V3.0/第2.5节工作共享结构:

以下限制适用于工作共享构件:

团队中的所有线程都必须遇到每个工作共享区域 或者根本没有。工作共享区域和屏障的顺序 对于团队中的每个线程,遇到的区域必须相同

在这种情况下,每个线程在输入显示结果的代码之前和之后都会遇到障碍

#include <omp.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int Aresult = 0;
    int Bresult = 0;

    omp_set_num_threads(6);
    #pragma omp parallel
    {
        int TID = omp_get_thread_num();

        while (1 == 1)
        {
            if (TID < 5)
            {
                // codeA
                #pragma omp atomic
                Aresult += TID + 1; // Aresult should be 1+2+3+4+5
            }
            else
            {
                // codeB
                Bresult = TID;
            }

            #pragma omp barrier

            // combine result from A and B
            #pragma omp single
            {
                //show result A and B
                printf ("Aresult = %d Bresult = %d\n", Aresult, Bresult);

                // set Aresult & Bresult to 0 for next iteration
                Aresult = Bresult = 0;
            }

            #pragma omp barrier
        }
    }

}
#包括
#包括
int main(int argc,char*argv[])
{
int Aresult=0;
int-Bresult=0;
omp_设置_数量_线程(6);
#pragma-omp并行
{
int TID=omp_get_thread_num();
而(1==1)
{
如果(TID<5)
{
//法典
#布拉格omp原子
Aresult+=TID+1;//Aresult应该是1+2+3+4+5
}
其他的
{
//法典
Bresult=TID;
}
#布拉格奥姆普屏障
//合并A和B的结果
#布拉格omp单曲
{
//显示结果A和B
printf(“Aresult=%d Bresult=%d\n”,Aresult,Bresult);
//为下一次迭代将Aresult&Bresult设置为0
Aresult=Bresult=0;
}
#布拉格奥姆普屏障
}
}
}

请避免多次问同一个问题。如果你想说得更清楚,只需编辑它。请避免多次问同一个问题。如果你想让它更清晰,只需编辑它。