2017-10-16 27 views
1

Selon le manuel de libgomp, un code sous la forme:ne comprends pas comment libgomp met en œuvre la Construct

#pragma omp parallel for 
for (i = lb; i <= ub; i++) 
    body; 

devient

void subfunction (void *data) 
{ 
    long _s0, _e0; 
    while (GOMP_loop_static_next (&_s0, &_e0)) 
    { 
    long _e1 = _e0, i; 
    for (i = _s0; i < _e1; i++) 
     body; 
    } 
    GOMP_loop_end_nowait(); 
} 

GOMP_parallel_loop_static (subfunction, NULL, 0, lb, ub+1, 1, 0); 
subfunction (NULL); 
GOMP_parallel_end(); 

J'ai fait un programme très petit pour déboguer juste pour voir comment cette mise en œuvre fonctionne:

int main(int argc, char** argv) 
{ 
    int res, i; 
    # pragma omp parallel for num_threads(4) 
    for(i = 0; i < 400000; i++) 
     res = res*argc; 

    return 0; 
} 

Ensuite, je courais gdb et points d'arrêt à "GOMP_parallel_loop_static" et « GOMP _parallel_end ". Au début, la bibliothèque n'était pas chargée, donc ils étaient en attente. Soit dit en un temps a manqué le programme de test gdb, je suis le résultat ci-dessous:

(gdb) run 2 1 6 5 4 3 8 7 
Starting program: ./test 2 1 6 5 4 3 8 7 
[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/lib/x86_64-linux- 
gnu/libthread_db.so.1". 
[New Thread 0x7ffff73c9700 (LWP 5381)] 
[New Thread 0x7ffff6bc8700 (LWP 5382)] 
[New Thread 0x7ffff63c7700 (LWP 5383)] 

Thread 1 "test" hit Breakpoint 2, 0x00007ffff7bc0c00 in GOMP_parallel_end() from /usr/lib/x86_64-linux-gnu/libgomp.so.1 

Comme vous pouvez le voir, il a atteint le deuxième point d'arrêt, dans « GOMP_parallel_end » mais pas la première. Je voudrais savoir comment cela pourrait être possible si le manuel de libgomp montre clairement que "GOMP_parallel_loop_static" vient en premier.

Merci.

+0

Vous avez les paramètres formels de 'main'' argv' et 'argc' dans le mauvais ordre. – tschwinge

Répondre

1

Cette partie de la documentation de GCC n'a pas vraiment été mise à jour régulièrement, donc c'est probablement une bonne idée de la lire seulement comme une approximation de ce qui se passe réellement. Si vous êtes intéressé par ce niveau de détail, je vous suggère de regarder les fichiers de débogage générés par -fdump-tree-all et des options similaires. Avec une version récente de GCC, votre exemple génère un appel à __builtin_GOMP_parallel, qui correspond à GOMP_parallel. Celui-là appelle en interne GOMP_parallel_end à la fin, donc c'est ce que vous voyez, je suppose.

void 
GOMP_parallel (void (*fn) (void *), void *data, unsigned num_threads, unsigned int flags) 
{ 
    num_threads = gomp_resolve_num_threads (num_threads, 0); 
    gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads)); 
    fn (data); 
    ialias_call (GOMP_parallel_end)(); 
} 

Bien sûr, les correctifs pour mettre à jour la documentation seront volontiers acceptés. :-)