OPENMP FOR CONSTRUCT GUIDED 调度方式实现原理和源码分析
前言
在本篇文章当中主要给大家介绍在 OpenMP 当中 guided 调度方式的实现原理。这个调度方式其实和 dynamic 调度方式非常相似的,从编译器角度来说基本上是一样的,在本篇文章当中就不介绍一些相关的必备知识了,如果不了解可以先看这篇文章 OpenMP For Construct dynamic 调度方式实现原理和源码分析 。
GUIDED 调度方式分析
我们使用下面的代码来分析一下 guided 调度的情况下整个程序的执行流程是怎么样的:
#pragma omp parallel for num_threads(t) schedule(guided, size)
for (i = lb; i <= ub; i++)
body;
编译器会将上面的程序编译成下面的形式:
void subfunction (void *data)
{
long _s0, _e0;
while (GOMP_loop_guided_next (&_s0, &_e0))
{
long _e1 = _e0, i;
for (i = _s0; i < _e1; i++)
body;
}
// GOMP_loop_end_nowait 这个函数的主要作用就是释放数据的内存空间 在后文当中不进行分析
GOMP_loop_end_nowait ();
}
GOMP_parallel_loop_guided_start (subfunction, NULL, t, lb, ub+1, 1, size);
subfunction (NULL);
// 这个函数在前面的很多文章已经分析过 本文也不在进行分析
GOMP_parallel_end ();
根据上面的代码可以知道,上面的代码当中最主要的两个函数就是 GOMP_parallel_loop_guided_start 和 GOMP_loop_guided_next,现在我们来分析一下他们的源代码:
- GOMP_parallel_loop_guided_start
void
GOMP_parallel_loop_guided_start (void (*fn) (void *), void *data,
unsigned num_threads, long start, long end,
long incr, long chunk_size)
{
gomp_parallel_loop_start (fn, data, num_threads, start, end, incr,
GFS_GUIDED, chunk_size);
}
static void
gomp_parallel_loop_start (void (*fn) (void *), void *data,
unsigned num_threads, long start, long end,
long incr, enum gomp_schedule_type sched,
long chunk_size)
{
struct gomp_team *team;
// 解析到底启动几个线程执行并行域的代码
num_threads = gomp_resolve_num_threads (num_threads, 0);
// 创建线程组
team = gomp_new_team (num_threads);
// 对共享数据进行初始化操作
gomp_loop_init (&team->work_shares[0], start, end, incr, sched, chunk_size);
// 启动线程组执行函数 fn
gomp_team_start (fn, data, num_threads, team);
}
在上面的程序当中 GOMP_parallel_loop_guided_start,有 7 个参数,我们接下来仔细解释一下这七个参数的含义: