OpenMP 如何知道嵌套了多少个循环实例

How can OpenMP know how many loop instances are nested?

本文关键字:循环 实例 多少 何知道 嵌套 OpenMP      更新时间:2023-10-16

我很久以前就使用OpenMP编写c ++程序。突然,一个问题出现在我的脑海中。

"OpenMP 如何知道嵌套了多少个循环实例?">

编译器是否显式计数?

OpenMP 运行时在线程局部变量中跟踪此信息。

libgomp,目前最流行的 OpenMP 实现之一可能是开源的;这意味着人们不仅可以完全免费地阅读其文档,还可以阅读其源代码。

omp_get_level()的实现如下:

int
omp_get_level (void)
{
  return gomp_thread ()->ts.level;
}

gomp_thread()的实施在这里。它检索指向线程本地结构的指针。

#if defined __nvptx__
extern struct gomp_thread *nvptx_thrs __attribute__((shared));
static inline struct gomp_thread *gomp_thread (void)
{
  int tid;
  asm ("mov.u32 %0, %%tid.y;" : "=r" (tid));
  return nvptx_thrs + tid;
}
#elif defined HAVE_TLS || defined USE_EMUTLS
extern __thread struct gomp_thread gomp_tls_data;
static inline struct gomp_thread *gomp_thread (void)
{
  return &gomp_tls_data;
}
#else
extern pthread_key_t gomp_tls_key;
static inline struct gomp_thread *gomp_thread (void)
{
  return pthread_getspecific (gomp_tls_key);
}
#endif

数据结构ts是一个struct gomp_team_state,其中包括:

  [...]
  /* Nesting level.  */
  unsigned level;
  /* Active nesting level.  Only active parallel regions are counted.  */
  unsigned active_level;
  [...]

每当使用#pragma omp parallel时,编译器都会将并行部分的主体提取到一个子函数中,并生成一组复杂的函数调用,最终导致gomp_team_start(),其中包含:

#ifdef LIBGOMP_USE_PTHREADS
void
gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
                 unsigned flags, struct gomp_team *team)
{
  [...]
  ++thr->ts.level;
  if (nthreads > 1)
    ++thr->ts.active_level;