使用libgomp中的GOMP_loop_static_start

时间:2015-11-02 18:06:46

标签: gcc openmp

当gcc编译器编译 selected = cmds.treeView (mytreeview, q=True, selectItem=True) 时,它从不调用ligbomp函数 GOMP_loop_static_start ,它使用一些汇编程序指令来执行 cmds.treeView(mytreeview, e=True, selectItem = ('thingToSelect', True)) 的功能。

我正在实现自己的libgomp库,我希望在OpenMP应用程序中调用#pragma omp for schedule(static) gcc编译器调用 GOMP_loop_static_start 的实现。

1 个答案:

答案 0 :(得分:1)

由于扩展了GOMP_loop_static_start指令,因此实际上不可能让GCC生成对for的调用,因为OpenMP扩展例程中的一段代码会使{{1}的情况快捷。 1}}:

schedule(static)

上面的代码来自GCC 4.2.0,这是第一个正式引入OpenMP支持的版本。从那时起,事情并没有太大变化(每个较新版本的OpenMP标准只会变得更加复杂)。 3123 static void 3124 expand_omp_for (struct omp_region *region) 3125 { 3126 struct omp_for_data fd; 3127 3128 push_gimplify_context (); 3129 3130 extract_omp_for_data (last_stmt (region->entry), &fd); 3131 region->sched_kind = fd.sched_kind; 3132 3133 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC 3134 && !fd.have_ordered 3135 && region->cont 3136 && region->exit) 3137 { 3138 if (fd.chunk_size == NULL) 3139 expand_omp_for_static_nochunk (region, &fd); 3140 else 3141 expand_omp_for_static_chunk (region, &fd); 3142 } 3143 else 3144 { 3145 int fn_index = fd.sched_kind + fd.have_ordered * 4; 3146 int start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index; 3147 int next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index; 3148 expand_omp_for_generic (region, &fd, start_ix, next_ix); 3149 } 3150 3151 pop_gimplify_context (NULL); 3152 } 分析extract_omp_for_data()指令和关联的for循环。它放置了for中找到的循环计划。如果未提供fd.sched_kind子句,则它使用GCC schedule的默认值。 schedule(static)expand_omp_for_static_nochunk()都不会调用expand_omp_for_static_chunk()。相反,它们会发出使用GOMP_loop_static_startomp_get_num_threads()来计算每个线程的迭代空间的代码:

omp_get_thread_num()

变为:

#pragma omp for
for (int i = 0; i < steps; i++)
  ...

只有<bb 2>: i = 0; steps.0 = steps; D.1368 = __builtin_omp_get_num_threads (); D.1369 = __builtin_omp_get_thread_num (); q.1 = steps.0 / D.1368; tt.2 = steps.0 % D.1368; if (D.1369 < tt.2) goto <bb 3>; else goto <bb 4>; <bb 3>: tt.2 = 0; q.1 = q.1 + 1; <bb 4>: D.1372 = q.1 * D.1369; D.1373 = D.1372 + tt.2; D.1374 = D.1373 + q.1; if (D.1373 >= D.1374) goto <bb 7>; else goto <bb 5>; <bb 5>: i = D.1373; <bb 6>: ... i = i + 1; if (i < D.1374) goto <bb 6>; else goto <bb 7>; <bb 7>: __builtin_GOMP_barrier (); 才能发出调用expand_omp_for_generic()的代码。为此,执行流程必须进入GOMP_loop_static_start块,如果循环调度不是静态的或者应用了else子句,则会发生这种情况。在前一种情况下,将调用另一个ordered。在后一种情况下,将调用GOMP_loop_xxx_start()

唯一剩下的选项是该区域没有延续(GOMP_loop_ordered_static_start())或退出(OMP_CONTINUE)块。我认为没有办法实现这一点,因为两个块总是由降低OpenMP OMP_RETURN指令的代码添加。更高版本的编译器删除了对退出块的检查,但对我来说仍然不明显,如何删除延续块。