据我了解,
我可以使用single
指令执行与使用sections
相同的工作,只需添加nowait
标记
以下代码与section
指令相比没有什么不同:
void main(){
#pragma omp parallel
{
int tid = omp_get_thread_num();
#pragma omp single nowait
{
printf("Thread %d in #1 single construct.\n", tid);
}
#pragma omp single nowait
{
printf("Thread %d in #2 single construct.\n", tid);
}
#pragma omp single nowait
{
printf("Thread %d in #3 single construct.\n", tid);
}
}
}
任何人都可以在不同情况下使用sections
和single
指令给我一些示例吗?
答案 0 :(得分:3)
首先,single
和sections
指令在阅读代码时使用明显不同的语义目的,而使用其中一个来模仿另一个可能会产生很大的误导。
关于技术性,single
是唯一支持copyprivate
子句的工作共享指令,其中:
...提供了一种使用私有变量的机制 从一个隐式任务的数据环境广播一个值到 属于的其他隐式任务的数据环境 平行区域。
另一方面,sections
工作共享结构支持lastprivate
和reduction
条款,single
不支持。
最后,请注意您的代码段:
#pragma omp single nowait
{
printf("Thread %d in #1 single construct.\n", tid);
}
#pragma omp single nowait
{
printf("Thread %d in #2 single construct.\n", tid);
}
#pragma omp single nowait
{
printf("Thread %d in #3 single construct.\n", tid);
} // No barrier here
不会模仿sections
,而是模仿sections nowait
。要模仿sections
,你必须记住让最后一个single
构造保持其隐含障碍。
答案 1 :(得分:2)
在某些情况下,single nowait
构造的行为可能与sections
构造的行为相同。但是,OpenMP规范只要求只有一个线程执行single
构造。它不要求空闲线程采用其他后续构造。您不能仅仅依赖于所有OpenMP实现的此行为。大多数人会做你期望的,但没有保证。
另一件值得一提的是,大多数实现都使用票证系统将single
区域分配给线程。 sections
的常用代码转换是通过将sections结构转换为for
循环并使用for
语句来映射到switch
工作共享构造。 1}}构造。因此,有一些关于执行的保证。
干杯, -Michael