Multithreading OpenMP while循环内并行
// 编辑:如何使5个线程同时运行代码A和第6个线程同时运行代码B,然后在所有线程都有代码后将结果传递到单个线程中?我读到我不允许使用关键字屏障 这是我的原始代码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) {
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;
}
#布拉格奥姆普屏障
}
}
}
请避免多次问同一个问题。如果你想说得更清楚,只需编辑它。请避免多次问同一个问题。如果你想让它更清晰,只需编辑它。