• [^] # Re: best-rating == column-major

    Posté par (site web personnel) . En réponse au journal Exercices de programmation et benchmarks. Évalué à 2. Dernière modification le 12 février 2020 à 09:17.

    Ce n'est pas évident que ce branchement soit inliné, il aurait été bien d'avoir un extrait du code assembleur, et de comparer avec une version sans multiplication.

    Bien vu ! Voici une version sur Compiler Explorer où on peu voir le corps de la version branchless :

    .L31:
     mov rdx, QWORD PTR [r8]
     movsx ecx, BYTE PTR [rdi+rax]
     mov edx, DWORD PTR [rdx+rax*4]
     mov esi, ecx
     imul ecx, edx
     add r12d, ecx
     test edx, edx
     setne dl
     and edx, esi
     mov BYTE PTR [rdi+rax], dl
     mov rdx, rax ; à partir de là on gère le compteur de la boucle et
     add rax, 1 ; la condition de sortie.
     cmp r9, rdx
     jne .L31 ; on a un seul jump par itération.

    et celui avec les branches :

    .L70:
     mov BYTE PTR [rdi+rax], 0 ; usable_column[i] = 0
    .L53:
     lea rdx, [rax+1] ; gestion du compteur de la boucle, sans intéret
     cmp rcx, rax ; pour la comparaison de la sortie asm
     je .L52 ; saut pour sortir de la boucle
    .L59:
     mov rax, rdx ; fin de la gestion du compteur de la boucle
    .L55:
     cmp BYTE PTR [rdi+rax], 0
     je .L53 ; un premier jump hors gestion du compteur de la boucle
     mov rdx, QWORD PTR [rsi]
     mov edx, DWORD PTR [rdx+rax*4]
     test edx, edx
     je .L70 ; là on a un jump qui va nous permettre de faire
     ; l'affectation usable_column[i] = 0 puis d'enchaîner avec
     ; la gestion du compteur de la boucle.
     ; Ça fusionne les deux sauts du code initial (le test
     ; if (v==0) puis le saut pour reboucler.
     add r12d, edx ; result += v
     lea rdx, [rax+1] ; à nouveau de la gestion du compteur de boucle
     cmp rcx, rax
     jne .L59