Я написал короткую программу на C с прагмой OpenMP, и мне нужно знать, в какую функцию libGOMP эта прагма транслируется GCC. Вот мой чудесный код:
#include <stdio.h>
#include "omp.h"
int main(int argc, char** argv)
{
int k = 0;
#pragma omp parallel private(k) num_threads(4)
{
k = omp_get_thread_num();
printf("Hello World from %d !\n", k);
}
return 0;
}
Чтобы сгенерировать промежуточный язык из GCC v8.2.0, я скомпилировал эту программу с помощью следующей команды:
gcc -fopenmp -o hello.exe hello.c -fdump-tree-ompexp
А результат дает:
;; Function main (main, funcdef_no=0, decl_uid=2694, cgraph_uid=0, symbol_order=0)
OMP region tree
bb 2: gimple_omp_parallel
bb 3: GIMPLE_OMP_RETURN
Added new low gimple function main._omp_fn.0 to callgraph
Introduced new external node (omp_get_thread_num/2).
Introduced new external node (printf/3).
;; Function main._omp_fn.0 (main._omp_fn.0, funcdef_no=1, decl_uid=2700, cgraph_uid=1, symbol_order=1)
main._omp_fn.0 (void * .omp_data_i)
{
int k;
<bb 6> :
<bb 3> :
k = omp_get_thread_num ();
printf ("Hello World from %d !\n", k);
return;
}
;; Function main (main, funcdef_no=0, decl_uid=2694, cgraph_uid=0, symbol_order=0)
Merging blocks 2 and 7
Merging blocks 2 and 4
main (int argc, char * * argv)
{
int k;
int D.2698;
<bb 2> :
k = 0;
__builtin_GOMP_parallel (main._omp_fn.0, 0B, 4, 0);
D.2698 = 0;
<bb 3> :
<L0>:
return D.2698;
}
Меня интересует вызов функции "__builtin_GOMP_parallel". Итак, я посмотрел исходный код libGOMP от GCC. Однако единственные вызовы функций, которые я нашел, были (из файла parallel.c):
GOMP_parallel_start (void (*fn) (void *), void *data, unsigned num_threads)
GOMP_parallel_end (void)
Итак, я могу себе представить, что вызов "__builtin_GOMP_parallel" определенным образом преобразуется в GOMP_parallel_start и GOMP_parallel_end. Как я могу быть уверен в этом предположении? Как я могу найти перевод встроенной функции на две другие, которые я нашел в исходном коде?
Спасибо
Ты почти понял. __builtin_GOMP_parallel
— это просто псевдоним компилятора для GOMP_parallel
(определенный в omp-builtins.def), который переводится очень поздно в компиляции, вы можете увидеть фактический вызов в сборке с gcc -S
.
GOMP_parallel_start(...);
fn(...);
GOMP_parallel_end();
Хорошо, я пропустил эту функцию в файле parallel.c, я не видел GOMP_parallel, только функции запуска и завершения. Вроде GOMP_parallel_start ваще не вызывается, а вместо него вызывается gomp_team_start (github.com/gcc-mirror/gcc/blob/gcc-8_3_0-release/libgomp/…) Спасибо
Если вы хотите посмотреть на ассемблерный код (что вы в итоге и сделали), Compiler Explorer — ваш друг... (Вот так: godbolt.org/z/-FliEb ). Затем вы также можете легко посмотреть на другие компиляторы.