假设我有一个运行某些操作的OpenMP 2.0 for循环:
#pragma omp parallel for schedule(static)
for (int i = 0; i < lim; ++i)
{
// do something thread-safe
}
threadSafeFunc();
unSafeFunc();
仿函数threadSafeFunc
完全是线程安全的,所以不是在完成所有迭代后连续运行它,我想得到第一个完成从OpenMP循环分配任务的线程开始工作它,然后让所有线程在串行执行unSafeFunc
之前等待。
我该怎么做?
答案 0 :(得分:3)
这可能是您特定问题的解决方案:
#pragma omp parallel
{ // #1
#pragma omp for schedule(static) nowait
for (int i = 0; i < lim; ++i) // #2
{
// do something thread-safe
} // No implied barrier bue to the nowait clause
#pragma omp single
{ // #3
threadSafeFunc();
} // Implied barrier
} // End of parallel region
unSafeFunc();
这个想法非常简单:首先在parallel
中打开#1
区域。在这个平行区域内,您使用两个工作共享结构:
#2
#3
循环结构(standard的第2.7.1节)有一个nowait
子句,它在循环结束时删除隐式屏障。然后是single
构造(第2.7.3节):
...指定关联的结构化块仅由执行 团队中的一个线程(不一定是主线程),in 其隐含任务的背景。团队中的其他线程,其中 不要执行该块,在结尾处等待一个隐含的障碍 单 ...
两个构造的组合确保第一个在循环中完成其工作的线程将进入single
构造并执行threadSafeFunc()
。然后所有线程将在隐含的屏障处同步并与master
线程连接。此时只有master
线程将继续并执行unSafeFunc()
。