2017-10-16 2 views
1

Nach dem libgomp Handbuch konstruieren, ein Code in der Form:kann nicht verstehen, wie libgomp implementiert die für

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

wird

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(); 

ich ein sehr kleines Programm habe gerade zu debuggen, um zu sehen, wie diese Implementierung funktioniert:

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; 
} 

Als nächstes lief ich gdb und Haltepunkte auf „GOMP_parallel_loop_static“ und „GOMP _parallel_end ". Zu Beginn war die Bibliothek nicht geladen, also waren sie ausstehend. Durch die Zeit, ein Prüfprogramm in gdb lief, bekam ich das Ergebnis unter:

(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 

Wie Sie sehen können, erreichte sie den zweiten Haltepunkt, in „GOMP_parallel_end“ aber nicht der erste. Ich würde gerne wissen, wie das möglich ist, wenn das libgomp-Handbuch klar zeigt, dass "GOMP_parallel_loop_static" zuerst kommt.

Vielen Dank.

+0

Sie haben 'main's formale Parameter' argv' und 'argc' in der falschen Reihenfolge. – tschwinge

Antwort

1

Dieser Teil der GCC-Dokumentation wurde nicht wirklich regelmäßig aktualisiert, daher ist es wahrscheinlich eine gute Idee, sie nur als Annäherung an das zu lesen, was tatsächlich passiert. Wenn Sie an dieser Detailgenauigkeit interessiert sind, schlage ich vor, dass Sie sich die von -fdump-tree-all und ähnlichen Optionen generierten Debug-Dateien ansehen.

Mit einer aktuellen Version von GCC generiert Ihr Beispiel einen Aufruf an __builtin_GOMP_parallel, der GOMP_parallel zugeordnet wird. Dieser ruft intern am Ende GOMP_parallel_end auf, also das, was Sie sehen, nehme ich an.

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)(); 
} 

Natürlich werden Patches zur Aktualisierung der Dokumentation gerne akzeptiert. :-)

Verwandte Themen