2015-11-02 23 views
0

使用GOMP_loop_static_start當gcc編譯器編譯它永遠不會調用ligbomp功能GOMP_loop_static_start#pragma omp for schedule(static),它使用一些彙編指令做#pragma omp for schedule(static)的功能。從libgomp

我實現我自己的libgomp庫,我想的是,當OpenMP的應用程序調用#pragma omp for static gcc編譯器調用我的實現GOMP_loop_static_start的。

+0

您可以查看英特爾貢獻的Clang的OSS運行時。它應該實現GOMP接口,但不受GPL病毒的阻礙,所以你可以用衍生作品做你想做的事情。 – Jeff

回答

1

這實際上是不可能得到GCC產生的,因爲在OpenMP的擴展程序的一段代碼的for指令擴張的結果GOMP_loop_static_start通話快捷鍵schedule(static)情況:

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 } 

上面的代碼來自GCC 4.2.0,這是第一個正式引入OpenMP支持的版本。自那時以來,事情並沒有多大變化(只有OpenMP標準的每個新版本都變得複雜得多)。 extract_omp_for_data()分析for指令和相關的for循環。它放置了在fd.sched_kind中找到的那種循環調度。如果沒有提供schedule子句,則它使用GCC 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)或退出(OMP_RETURN)塊。我認爲沒有辦法實現這一點,因爲兩個塊總是由降低OpenMP for指令的代碼添加。後期版本的編譯器刪除了退出塊的檢查,但對我而言仍然不明顯,繼續塊如何被刪除。