- Cet article présente une implémentation générique de recherche binaire en C++ plus courte et deux fois plus rapide que la fonction standard
std::lower_bound.
- La nouvelle implémentation est dite « branchless » car elle est compilée en instructions de déplacement conditionnel plutôt qu’en branchements/sauts conditionnels.
- La recherche binaire fonctionne en divisant une liste triée en deux parties à l’élément du milieu, puis en comparant la valeur médiane à la valeur recherchée. En fonction du résultat de la comparaison, on décide dans laquelle des deux sous-listes poursuivre la recherche.
- L’article aborde aussi le concept de prédiction de branchement, une technique qui permet au processeur d’exécuter des instructions en parallèle pour gagner en vitesse. Mais comme la recherche binaire est imprévisible, la prédiction de branchement n’est pas idéale ici.
- L’auteur présente une nouvelle implémentation de recherche binaire,
sb_lower_bound, plus rapide que l’implémentation standard et que la version branchless_lower_bound, car elle contient nettement moins d’instructions dans la boucle.
- L’auteur présente également une version encore plus rapide,
bb_lower_bound, qui utilise une autre méthode pour partitionner la liste de recherche.
- L’article se conclut par une suggestion : si la partie la plus lente de votre programme comprend des recherches et/ou comparaisons que le processeur ne peut pas prédire, essayez
clang avec -mllvm -x86-cmov-converter=false. Et si vous avez besoin d’une recherche binaire plus rapide, essayez sb_lower_bound.
- L’auteur fournit aussi le code de ces nouvelles implémentations de recherche binaire et discute en détail des performances de chacune.
- L’article a également été mis à jour avec une version refactorisée de
sb_lower_bound qui réduit le nombre d’instructions assembleur dans la boucle critique de 9 à 8, ce qui améliore légèrement la vitesse.
- L’auteur aborde aussi le concept de prefetching, qui consiste à faire remonter certaines zones mémoire dans le cache afin que, lorsque les données préchargées deviennent réellement nécessaires, seules les latences du cache L1/L2 s’appliquent. Une version de
sb_lower_bound avec prefetching ajouté pour 256 KB+ est également fournie.
- Cet article est signé Mihail Dumitrescu et a été publié le 24 juin 2023.
1 commentaires
Commentaires sur Hacker News
lowerBound.sb_lower_boundpour les types primitifs etstd::lower_bounddans les autres cas.cmov, et fournit un lien pour plus d’informations.