首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何停止OpenMP 2.0的并行区域

如何停止OpenMP 2.0的并行区域
EN

Stack Overflow用户
提问于 2019-01-21 15:29:28
回答 1查看 1.3K关注 0票数 1

我想找个更好的办法取消我的线程。在我的方法中,我使用一个共享变量,如果设置了这个变量,我只会抛出一个继续。这很快就完成了我的线程,但理论上线程一直在产卵和结束,这似乎不太优雅。那么,是否有更好的方法来解决这个问题(break不受我的OpenMP支持)?

我必须使用Visual,所以我的OpenMP Lib已经过时了,这是无法避免的。因此,我认为#omp cancel将无法工作

代码语言:javascript
运行
复制
int progress_state = RunExport;
#pragma omp parallel
{
#pragma omp for
  for (int k = 0; k < foo.z; k++)
  for (int j = 0; j < foo.y; j++)
  for (int i = 0; i < foo.x; i++) {
    if (progress_state == StopExport) {
      continue;
    }

// do some fancy shit 

// yeah here is a condition for speed due to the critical
#pragma omp critical
    if (condition) {
      progress_state = StopExport;
    }
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-21 16:12:13

您应该以“如果请求取消的话,在所有剩余的迭代中只使用continue”的简单方法来完成这个任务。这可能只是最外层循环中的第一次检查(并且考虑到您有几个嵌套循环,这可能没有任何可测量的开销)。

代码语言:javascript
运行
复制
std::atomic<int> progress_state = RunExport;

// You could just write #pragma omp parallel for instead of these two nested blocks.
#pragma omp parallel
{
#pragma omp for
  for (int k = 0; k < foo.z; k++)
  {
    if (progress_state == StopExport)
      continue;

    for (int j = 0; j < foo.y; j++)
    {
      // You can add break statements in these inner loops.
      // OMP only parallelizes the outermost loop (at least given the way you wrote this)
      // so it won't care here.
      for (int i = 0; i < foo.x; i++)
      {

        // ...

        if (condition) {
          progress_state = StopExport;
        }
      }
    }
  }
}

一般来说,OMP不会突然产生新线程或结束现有线程,特别是在一个并行区域内。这意味着运行一些更小的迭代所带来的开销很小。考虑到在您的情况下,默认调度很可能是static,这甚至更正确,这意味着每个线程都知道它的开始和结束索引。其他调度模式将不得不在每次迭代(或每几次迭代)中调用OMP运行时来请求更多的工作,但在这里不会发生这种情况。编译器将基本上看到线程工作的代码:

代码语言:javascript
运行
复制
// Not real omp functions.
int myStart = __omp_static_for_my_start();
int myEnd = __omp_static_for_my_end();
for (int k = myStart; k < myEnd; ++k)
{
  if (progress_state == StopExport)
    continue;

  // etc.
}

您可以尝试一个非原子线程本地“我应该取消吗?”标志,以false开头,只能更改为true (编译器可以理解该标记并折叠到循环条件中)。但我怀疑无论哪种方式,您都会看到巨大的开销,至少在x86上,int是原子的。

似乎不优雅

OMP 2.0在优雅方面不太好用。我的意思是,迭代std::vector需要至少一个static_cast来沉默已签名的->无符号转换警告。因此,除非您有这种模式导致性能问题的具体证据,否则没有什么理由不使用它。

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

https://stackoverflow.com/questions/54293086

复制
相关文章

相似问题

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