2019-01-04 OMPi知识清单

"OpenMP taskwait 函数"

Posted by MetaNetworks on January 4, 2019
本页面总访问量

#ort_taskwait() 源码

  1. How = 0 (wait for my children)
  2. How = 1 (wait for all team tasks)
  3. How = 2 (wait at the end of parallel)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void ort_taskwait(int how)
{
  ort_eecb_t *me = __MYCB;
  int        victim = NO_VICTIM_LEFT;
 
  if (me->num_siblings == 1)
    return;
  else if(how < 2 && me->parent->tasking.never_task == 0)
    return;
  else if(how == 2)
  {//并行域级别的等待
    parallel_barrier_wait(&me->parent->barrier, me->thread_num);
    return;
  }
 
  if (how > 0)
  {//帮助组内其他线程完成任务
    do{
      while((victim = ort_task_execute(me, victim)) != NO_TASKS_LEFT)
    ;
    }while ((victim = check_for_tasks(me)) != NO_VICTIM_LEFT);
  }
  else//只等待当前任务的子任务全部完成
    while (__CURRTASK(me)->num_children > 0)
      ort_task_execute(me, victim);
}

代码实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void f()
{
    return;
}

int main()
{
	#pragma omp parallel
    {
        #pragma omp task
        {
            f();
        }
        #pragma omp taskwait
    }
    return 0;
    
}

OMPi转换后,去除不必要的注释等内容后的代码:

  • taskwait 体现在 static void * thrFunc0(void * __arg) 函数中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
void f()
{
  return;
}

int __original_main(int _argc_ignored, char ** _argv_ignored)
{
  {
    ort_execute_parallel(_thrFunc0_, (void *) 0, -1, 0, 1);
  }
  # 17 "test.c"
  return (0);
}

static void * _thrFunc0_(void * __arg)
{
  {
    if (omp_in_final() || ort_task_throttling())
      {
        void * _itn;
        _itn = ort_task_immediate_start(0);
        {
          f();
          CANCEL_task_11 :
            ;
        }
        ort_task_immediate_end(_itn);
      }
    else
      {
        ort_new_task(_taskFunc0_, (void *) 0, 0, 0);
      }
    ort_taskwait(0);
  }
  CANCEL_parallel_9 :
    ort_taskwait(2);
  return ((void *) 0);
}


static void * _taskFunc0_(void * __arg)
{
  {
    f();
  }
  return ((void *) 0);
}