Dans un programme que j'ai écrit, 20 % du temps est passé à trouver le minimum de 3 nombres dans une boucle interne, dans cette routine :
static inline unsigned int
min(unsigned int a, unsigned int b, unsigned int c)
{
unsigned int m = a;
if (m > b) m = b;
if (m > c) m = c;
return m;
}
Y a-t-il un moyen d'accélérer cela ? Je suis d'accord avec du code en langage d'assemblage pour x86/x86_64.
Éditer : En réponse à certains commentaires :
* Le compilateur utilisé est gcc 4.3.3
* En ce qui concerne l'assemblage, je suis seulement un débutant. J'ai demandé de l'assemblage ici, pour apprendre comment faire. :)
* J'ai un Intel 64 quad-core, donc les MMX/SSE etc. sont supportés.
* Il est difficile de poster la boucle ici, mais je peux vous dire que c'est une implémentation très optimisée de l'algorithme de Levenshtein.
Voici ce que le compilateur me donne pour la version non inlinée de min :
.globl min
.type min, @function
min:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %eax
movl 16(%ebp), %ecx
cmpl %edx, %eax
jbe .L2
movl %edx, %eax
.L2:
cmpl %ecx, %eax
jbe .L3
movl %ecx, %eax
.L3:
popl %ebp
ret
.size min, .-min
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
La version inline est incluse dans le code optimisé -O2 (même mes marqueurs mrk = 0xfefefefe, avant et après l'appel à min()) sont optimisés par gcc, donc je n'ai pas pu y accéder.
Mise à jour : J'ai testé les changements suggérés par Nils, ephemient, cependant il n'y a pas de gain de performance perceptible en utilisant les versions en langage d'assemblage de min(). Cependant, j'obtiens un gain de performance de 12,5 % en compilant le programme avec -march=i686, ce qui je suppose est dû au fait que l'ensemble du programme bénéficie des nouvelles instructions plus rapides que gcc génère avec cette option. Merci pour votre aide.
Remarque - J'ai utilisé le profileur ruby pour mesurer les performances (mon programme C est une bibliothèque partagée chargée par un programme ruby), donc je pouvais obtenir le temps passé uniquement pour la fonction C de niveau supérieur appelée par le programme ruby, qui finit par appeler min() dans la pile. Veuillez consulter cette question.