当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 的实现。
答案 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_start
和omp_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
指令的代码添加。更高版本的编译器删除了对退出块的检查,但对我来说仍然不明显,如何删除延续块。