2017-10-17 32 views
2

J'étudie le flux d'exécution d'un programme OpenMP lié à libgomp. Il utilise le #pragma omp parallel for. Je sais déjà que cette construction devient, entre autres, une fonction appel à GOMP_parallel, qui est mis en œuvre comme suit:Objdump démonter ne correspond pas au code source

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

Lors de l'exécution objdump -d sur libgomp, GOMP_parallel apparaît comme:

000000000000bc80 <[email protected]@GOMP_4.0>: 
bc80: 41 55     push %r13 
bc82: 41 54     push %r12 
bc84: 41 89 cd    mov %ecx,%r13d 
bc87: 55      push %rbp 
bc88: 53      push %rbx 
bc89: 48 89 f5    mov %rsi,%rbp 
bc8c: 48 89 fb    mov %rdi,%rbx 
bc8f: 31 f6     xor %esi,%esi 
bc91: 89 d7     mov %edx,%edi 
bc93: 48 83 ec 08    sub $0x8,%rsp 
bc97: e8 d4 fd ff ff   callq ba70 <[email protected]@GOMP_1.0+0x70> 
bc9c: 41 89 c4    mov %eax,%r12d 
bc9f: 89 c7     mov %eax,%edi 
bca1: e8 ca 37 00 00   callq f470 <[email protected]@OMP_3.1+0x2c0> 
bca6: 44 89 e9    mov %r13d,%ecx 
bca9: 44 89 e2    mov %r12d,%edx 
bcac: 48 89 ee    mov %rbp,%rsi 
bcaf: 48 89 df    mov %rbx,%rdi 
bcb2: 49 89 c0    mov %rax,%r8 
bcb5: e8 16 39 00 00   callq f5d0 <[email protected]@OMP_3.1+0x420> 
bcba: 48 89 ef    mov %rbp,%rdi 
bcbd: ff d3     callq *%rbx 
bcbf: 48 83 c4 08    add $0x8,%rsp 
bcc3: 5b      pop %rbx 
bcc4: 5d      pop %rbp 
bcc5: 41 5c     pop %r12 
bcc7: 41 5d     pop %r13 
bcc9: e9 32 ff ff ff   jmpq bc00 <[email protected]@GOMP_1.0> 
bcce: 66 90     xchg %ax,%ax 

D'abord, il n'y a pas d'appel à GOMP_ordered_end dans le code source de GOMP_parallel, par exemple. En second lieu, cette fonction se compose de:

void 
GOMP_ordered_end (void) 
{ 
} 

Selon la sortie objdump, cette fonction commence à ba00 et se termine à bbbd. Comment pourrait-il avoir autant de code dans une fonction qui est vide? A propos, il y a un commentaire dans le code source de libgomp indiquant qu'il ne devrait apparaître que lors de l'utilisation de la construction ORDERED (comme son nom l'indique), ce qui n'est pas le cas de mon test. Enfin, la principale préoccupation ici pour moi est: pourquoi le code source diffère-t-il tellement du démontage? Pourquoi, par exemple, n'y at-il aucune mention à gomp_team_start dans l'assemblée?

Le système a gcc version 5.4.0

+1

inline gcc petites fonctions. Certaines de ces "fonctions" pourraient même être des macros CPP. –

+3

Il n'y a pas d'appel 'GOMP_ordered_end' dans votre sortie' objdump -d '. Au lieu de cela, il y a un appel à 'GOMP_ordered_end @@ GOMP_1.0 + 0x70' qui est une fonction sans nom qui se trouve 0x70 octets après le début de' GOMP_ordered_end @@ GOMP_1.0'. –

+0

Si vous pensez vraiment que le code compilé est différent de la source, la première étape consiste à regarder le code après l'expansion de la macro C ('gcc -E'). L'étape suivante consiste à regarder le code d'assemblage produit ('gcc -S'). – dirkt

Répondre

3

Selon la sortie objdump, cette fonction commence à BA00 et se termine à BBBD. Comment pourrait-il avoir autant de code dans une fonction qui est vide? La fonction elle-même est petite mais GCC a juste utilisé quelques octets supplémentaires pour aligner la fonction suivante et stocker des données statiques (problème utilisé par d'autres fonctions dans ce fichier). Voici ce que je vois dans ordered.o locale:

00000000000003b0 <GOMP_ordered_end>: 
3b0: f3 c3     repz retq 
3b2: 66 66 66 66 66 2e 0f data32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1) 
3b9: 1f 84 00 00 00 00 00 

D'abord, il n'y a aucun appel à GOMP_ordered_end dans le code source de GOMP_parallel, par exemple.

Ne vous laissez pas distraire par [email protected]@GOMP_1.0+0x70 marque dans le code assembleur. Tout ce qu'il dit est que cela appelle une fonction de bibliothèque locale (pour laquelle objdump n'a trouvé aucune information de symbole) qui se trouve à 112 octets après GOMP_ordered_end. C'est probablement gomp_resolve_num_threads. Pourquoi, par exemple, n'y at-il aucune mention à gomp_team_start dans l'assemblage?

Hm, cela ressemble à peu près comme ça:

bcb5: e8 16 39 00 00   callq f5d0 <[email protected]@OMP_3.1+0x420> 
+0

L'alignement n'est pas suffisant pour expliquer les octets '0xbd' pour une fonction vide. Quelque chose d'autre doit se passer. –

+0

@yugr Je voulais vraiment dire "GOMP_ordered_end". Ce que j'essayais de dire est: Comment "GOMP_ordered_end" est apparu dans le démontage de "GOMP_parallel", mais il n'y a pas d'appel à cette fonction sur le code source? –

+0

@ MárcioJales Got it, j'ai mis à jour la réponse. – yugr