Maison  >  Article  >  développement back-end  >  Comment les instructions SSE et l'optimisation de l'assemblage peuvent-elles améliorer les performances d'un algorithme de dénombrement de population avec une boucle à deux niveaux ?

Comment les instructions SSE et l'optimisation de l'assemblage peuvent-elles améliorer les performances d'un algorithme de dénombrement de population avec une boucle à deux niveaux ?

Linda Hamilton
Linda Hamiltonoriginal
2024-10-26 00:17:28967parcourir

 How can SSE instructions and assembly optimization improve the performance of a population count algorithm with a two-level loop?

Comprendre le problème

Dans votre code, vous gérez les décomptes de population dans une boucle à deux niveaux et essayez d'optimiser la boucle interne avec l'assemblage. La boucle parcourt une tranche d'octets et utilise la fonction __mm_add_epi32_inplace_purego pour ajouter des popcounts positionnels à un tableau.

Optimisation via Assembly

Pour optimiser la boucle interne, vous pouvez implémenter __mm_add_epi32_inplace_purego dans l'assembly. Vous trouverez ci-dessous la version optimisée suggérée de la fonction :

<code class="assembly">.text
.globl __mm_add_epi32_inplace_purego
__mm_add_epi32_inplace_purego:
    movq rdi, [rsi]
    movq rsi, [rdi+8]
    addq rsi, rdi
    movups (%rsi, %rax, 8), %xmm0
    addq , %rsi
    movups (%rsi, %rax, 8), %xmm1
    paddusbd %xmm0, %xmm0
    paddusbd %xmm1, %xmm1
    vextracti128 <pre class="brush:php;toolbar:false"><code class="assembly">.text
.globl __optimized_population_count_loop
__optimized_population_count_loop:
    movq rdi, [rsi]
    leaq (0, %rdi, 4), %rdx  # multiple rdi by 4, rdx = counts
    movq rsp, r11
    and rsp, -16
    subq r15, r11
    movq r15, r9
    mov rdi, (%rsi)
    movq r15, rsi
    mov %rsi, rsi
    pxor %eax, %eax
    dec %rsi

.loop:
    inc %rsi
    addq , rsi
    cmp rsi, rdi
    cmovge %rsi, rsi
    movsw (%rdi, %rax, 2), %ax
    movsw (%rsi, %rax, 2), %dx
    movw %ax, (%rdx)
    movw %dx, 2(%rdx)

.end_loop:</code>
, %xmm0, %eax vextracti128 , %xmm1, %edx addl %eax, (%rdi) addl %edx, 4(%rdi) addl %r8d, (%rdi) ret

Explication :

Ce code assembleur optimise la fonction à l'aide d'instructions SSE compressées. Il :

  • Calcule les popcounts en blocs de 16 bits à l'aide de paddusbd.
  • Extrait la partie inférieure de 128 bits à l'aide de vextracti128.
  • Ajoute les résultats au [8 ]int32 à l'adresse indiquée par %rdi.

Boucle entière améliorée avec assemblage

Explication :

Le tableau complet la boucle est désormais optimisée en assemblage. Il utilise :

  • Une boucle pour traiter des morceaux de 2 octets.
  • Le streaming se charge via un addq $32 consécutif, rsi pour éviter les manques de cache.
  • Un outil rapide et compact moyen d'enregistrer les résultats à l'aide de movw.

Conclusion

Cette version optimisée devrait améliorer considérablement les performances de votre algorithme de calcul des décomptes de population positionnelles.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn