Developpez.com - Rubrique C++

Le Club des Développeurs et IT Pro

Sortie de LLVM et Clang 5.0

Avec des améliorations de performance pour beaucoup de processeurs et une implémentation des coroutines

Le 2017-09-12 00:40:11, par dourouc05, Responsable Qt & Livres
Approximativement selon le calendrier prévu, voici donc la version 5.0 de LLVM, y compris le compilateur C et C++ Clang. En peu de mots, cette version apporte la compatibilité avec pas mal de matériels récents ; côté C++, on compte C++17 au complet et les coroutines (qui apparaîtront probablement dans une prochaine version de C++), en utilisant les fonctionnalités arrivées avec LLVM 4.0.

Cette version apporte énormément de nouveautés du côté matériel, pour les architectures ARM, AVR, MIPS, PowerPC 3.0, x86, ainsi que les GPU AMD Radeon Vega. Plus en détail, pour l’architecture ARM, la sélection d’instructions et la fusion d’instructions ont été fortement améliorées, ce qui devrait avoir un impact non négligeable sur la performance. Les instructions ARMv8.1, 8.2 et 8.3 ont été ajoutées au compilateur (comme les Cortex M23 et M33). Les données de l’ordonnanceur Cavium ThunderX2 ont été ajoutées, ce qui devrait améliorer fortement la performance pour ce processeur prévu pour les centres informatiques et superordinateurs.

Bien évidemment, la famille x86 n’est pas oubliée. Dans les processeurs ajoutés, on compte AMD Ryzen (les données pour l’ordonnanceur seront encore améliorées avec LLVM 6.0) et Intel Goldmont (la dernière génération de Pentium, Celeron et Atom). Pas mal de modifications ont eu lieu du côté AVX-512, les instructions vectorielles des Xeon haut de gamme. Les données concernant une série de processeurs plus anciens ont été mises à jour (Intel Silvermont — Atom, Celeron et Pentium de 2013 — et Sandy Bridge — Core 2e génération —, AMD Jaguar — 2013).

Plus spécifiquement, pour Clang, les coroutines sont une des fonctionnalités les plus attendues pour la version 5.0. N’étant pas encore dans la norme C++, il faut les activer séparément (-fcoroutines-ts -stdlib=libc++). Une coroutine est une fonction particulière qui peut suspendre et reprendre son exécution tout en gardant son état. Une utilisation assez simple est d’éviter de générer explicitement une liste d’éléments à travers laquelle le programme itère — notamment dans le cas où cette liste est infinie. Ainsi, on pourrait écrire ceci pour afficher tous les nombres en partant de zéro jusqu’à l’infini par pas de cinq (0, 5, 10, etc.) :

Code :
1
2
3
4
5
6
7
8
9
10
generator generatorForNumbers(int begin, int inc= 1){
  for (int i= begin;; i += inc){
    co_yield i;
  }
}

int main(){
  for (auto n: getForNumbers(0, 5)) 
    std::cout << n << " ";
}


Ces coroutines auront ainsi une certaine utilité notamment dans les applications par événements, comme un serveur Web (en attendant des requêtes) ou une interface graphique (idem pour des interactions avec l’utilisateur). Elles peuvent aussi avoir des applications pour le multitâche coopératif, où chaque tâche à effectuer décide du moment où elle rend l’exécution aux autres tâches (alors qu’un appel de fonction est préemptif : les autres fonctions ne peuvent s’exécuter qu’à la fin de l’actuelle). Ainsi, un serveur Web pourrait s’écrire comme ceci :

Code :
1
2
3
4
5
6
7
Acceptor acceptor{80};
while (true){
  Socket socket = co_await acceptor.accept(); // Exécuté dès qu'une nouvelle connexion arrive. 
  auto request = co_await socket.read(); // Dès qu'un paquet est disponible. 
  auto response = handleRequest(request); 
  socket.write(responste); 
}
Voir aussi : les notes de version de LLVM 5.0 et de Clang 5.0.
  Discussion forum
1 commentaire
  • ParseCoder
    Membre averti
    Quelque chose de très intéressant avec cette nouvelle version également: l'intégration du solver SMT z3 pour l'analyseur statique, ce qui lui permet de gérer des cas beaucoup plus complexes. Mais il faut positionner un flag spécifique lors de la compilation de Clang pour que cette fonctionalité soit active. Les perfs de l'analyseur en pâtissent mais c'est normal, tout a un coût.