AMD annonce la première carte graphique avec SSD intégré, nommée Radeon Pro SSG

La bataille des annonces fait rage cette semaine, au SIGGRAPH : NVIDIA a annoncé ses cartes graphiques haut de gamme et professionnellesde dernière génération, des bêtes de calcul (Quadro P5000 et P6000 pour les professionnels, Titan X Pascal pour les particuliers) ; AMD réplique sur un autre terrain. Ici, il n’est pas question de performance brute (Polaris n’a pas l’air d’arriver à battre à plates coutures les dernières avancées de NVIDIA), mais bien de mémoire : AMD ajoute un SSD sur certaines cartes.

En effet, les cartes graphiques actuelles sont surtout limitées au niveau de la bande passante du bus PCIe, pour envoyer des données du processeur principal vers la carte graphique. Leur mémoire est déjà assez grande dans la gamme professionnelle (jusque vingt-quatre gigaoctets par carte chez NVIDIA, trente-deux chez AMD), mais pas toujours suffisante pour gérer de très importantes quantités de données, que ce soit pour la prospection de gaz et de pétrole (et les applications en ingénierie, de manière générale), l’affichage de grandes scènes détaillées en réalité virtuelle (par exemple, pour des applications médicales)… ou l’encodage de vidéos 8K (pour la création de contenu). Dans ce cas, si toutes les données ne peuvent pas être présentes sur la mémoire de la carte, une partie est déchargée dans la mémoire centrale ou sur le stockage de masse de la machine, en transitant par le bus PCIe — ce qui dégrade la performance.

L’idée d’AMD est d’ajouter un SSD directement au niveau de la carte graphique : ainsi, elle pourra disposer d’un stockage très imposant (un téraoctet !) accessible facilement, sans délai de transit dans un bus « lent ». Cela pourra accélérer de plusieurs ordres de grandeur certains traitements très gourmands en mémoire et en bande passante. Selon les informations disponibles actuellement, la carte dispose de deux ports au format M.2, prévus pour connecter ces SSD.

Les résultats sont impressionnants pour les prototypes actuels : AMD a réussi à encoder une vidéo 8K (7680 pixels de large, 4320 pixels de haut, c’est-à-dire une trentaine de mégapixels) à raison de nonante-six images par seconde, contre dix-sept pour le même GPU mais sans SSD. Ce gain se paie : il est possible de commande des kits de développement au prix de 9999 $, avec une mise à disposition au grand public à l’horizon 2017.

Source : AMD Radeon™ Pro SSG Set to Transform Workstation PC Architecture, and to Shatter Real-Time Visual Computing Barriers, AMD Announces Radeon Pro SSG: Polaris With M.2 SSDs On-Board (image).

Sortie de OpenMPI 2.0

MPI (message passing interface) est une norme très utilisée pour programmer des superordinateurs. De manière plus générale, l’API sert à distribuer des calculs sur plusieurs machines (jusque des centaines de milliers de processeurs), sans forcément l’architecture lourde d’un superordinateur ou d’un centre informatique (quelques machines sur un réseau Ethernet suffisent, pas besoin de connexions spécifiques comme InfiniBand). De manière générale, MPI lance le même programme sur tous les ordinateurs du réseau ; ces derniers peuvent alors communiquer en envoyant (MPI_Send) et en recevant des messages (MPI_Recv) de manière synchronisée — pour les fonctionnalités de base.

Cette norme compte principalement deux implémentations libres : MPICH, l’historique, dont beaucoup de versions commerciales dérivent (comme Intel ou Microsoft), l’implémentation de référence ; OpenMPI, qui a débuté comme une implémentation alternative par plusieurs universités et centres de recherche, parfois plus rapide à l’exécution. Cette dernière vient de voir une nouvelle version majeure, OpenMPI 2.0. Celle-ci apporte bon nombre de changements par rapport à la version précédente, 1.10 : la compatibilité binaire est d’ailleurs cassée, il faudra recompiler les applications pour profiter d’OpenMPI 2.0.

Au niveau normatif, cette nouvelle version est compatible avec MPI 3.1, la dernière version, parue en juin 2015. Elle n’apporte que des changements mineurs par rapport à la précédente.

Plus important, l’accès à la mémoire des autres ordinateurs coordonnés à travers MPI (RMA) a été largement amélioré. Ces fonctionnalités servent à lire directement de la mémoire sur un autre ordinateur du réseau, sans besoin de communication synchrone supplémentaire entre les deux machines : seul l’ordinateur qui a besoin des informations est bloqué en les attendant, celui qui est censé les envoyer n’a aucun traitement spécifique à effectuer (tout est géré par MPI). Ces opérations étant assez courantes à effectuer, des interfaces de communication comme InfiniBand proposent des opérations similaires : OpenMPI peut maintenant les exploiter.

OpenMPI améliore sa gestion des ressources pour exploiter à leur plein potentiel des supercalculateurs d’un exaflops (actuellement, ils plafonnent à quelques dizaines de pétaflops). Ainsi, la consommation de mémoire au lancement des processus est limitée pour de très grands nombres de machines en évitant d’initialiser trop tôt des structures de données coûteuses (paramètre mpi_add_procs_cutoff). La communication entre les ordonnanceurs des superordinateurs et les applications pourra se faire avec l’interface PMIx — ce qui représente une étape importante pour gérer au mieux la puissance de calcul disponible.

Sources : [Open MPI Announce] Open MPI v2.0.0 released, Open MPI gets closer to exascale-ready code.
Merci à Claude Leloup pour ses corrections.

FUJITSU passe à l’architecture ARM pour ses prochains superordinateurs

Dans le dernier classement des superordinateurs les plus puissants, FUJITSU classe une de ses machines à la cinquième position, la plus puissante au monde en dehors de la Chine et des États-Unis (elle était la plus puissante lors de sa construction, en 2011) ; elle est installée chez RIKEN, le plus grand institut de recherche japonais. K utilise des processeurs avec une architecture SPARC64, quand la majorité des supercalculateurs listés utilise la plus conventionnelle x86, la même qui équipe la majorité des ordinateurs personnels.

Cependant, FUJITSU abandonne le SPARC64 pour ses prochains superordinateurs : la société japonaise passera à l’ARM, architecture actuellement reine dans les applications embarquées, notamment les téléphones portables. Cette annonce a été faite à la conférence ISC, lors de la présentation sur le futur des superordinateurs de la marque, dont le remplaçant du K installé chez RIKEN. Il vise l’échelle de l’exaflops (comme les Américains) pour 2020.

Au niveau technologique, la microarchitecture de ces futurs processeurs (qui sert à implémenter les instructions accessibles en assembleur) devrait être similaire à l’actuelle, mais l’architecture ARM devrait mieux l’exploiter, selon les dires de FUJITSU. Actuellement, peu de détails sont cependant disponibles au niveau technique, le projet devant aboutir d’ici à peu près quatre ans.

La stratégie de FUJITSU semble se réorienter : alors que leur avantage compétitif s’amenuise, ils devaient réagir et exploiter un écosystème déjà existant (afin de limiter en partie leurs coûts, vu la faible production en systèmes HPC de FUJITSU). Trois architectures principales coexistent dans le secteur HPC : x86 (Intel et AMD), POWER (IBM) et ARM. La gamme de serveurs FUJITSU inclut les PRIMERGY, qui utilisent des processeurs Intel x86 : il restait à faire un choix entre ARM et POWER.

Le côté ARM est nettement moins développé que POWER pour du calcul scientifique de très haute performance, ce qui laisse une chance à FUJITSU de se différentier (seul Cavium est présent sur ce marché, avec ses ThunderX). De plus, la communauté ARM a une grande expérience quand il s’agit de diminuer la consommation énergétique, à cause des besoins des applications mobiles. Cependant, l’architecture ARM aura besoin d’extensions pour les applications HPC, notamment pour vectoriser les opérations de calcul : FUJITSU travaille main dans la main avec ARM.

Le marché HPC semble récemment se dynamiser, la position dominante d’Intel étant mise à mal : tant par IBM et son architecture POWER que les accélérateurs NVIDIA ou FUJITSU, avec l’arrivée d’AMD sur ce marché.

Source et image : Fujitsu Switches Horses for Post-K Supercomputer, Will Ride ARM into Exascale.

IBM annonce sa feuille de route pour son architecture POWER9

Dans le monde des serveurs, Intel règne à peu près sans partage en ce qui concerne les processeurs utilisés, notamment avec sa gamme de Xeon. Cependant, sa place est convoitée dans ce marche lucratif : d’un côté par ARM, des processeurs bien plus simples et qui permettent de stocker plus de processeurs avec plus de cœurs (bien plus lents) pour la même consommation énergétique ; de l’autre par IBM et son architecture POWER, concurrent de longue date d’Intel (une architecture de la même famille que les PowerPC chers à Apple, avant de passer chez Intel il y a dix ans).

Après avoir lancé l’OpenPOWER Foundation en 2013 avec la nouvelle version de son architecture POWER8, voici venu, pour IBM, le temps des premières annonces sur sa prochaine architecture, dénommée POWER9. La caractéristique mise en avant est que ces processeurs POWER9 auront vingt-quatre cœurs (par rapport aux vingt-deux proposés récemment par Intel dans ses Xeon E5 v4), soit le double de la génération actuelle POWER8 ; ils devraient arriver dans la seconde moitié de 2017 et seront utilisés pour le supercalculateur américain Summit.

Quelques détails plus croustillants sont d’ores et déjà disponibles sur le processeur lui-même : la gravure se fera en 14 nm (comme les processeurs Intel de dernière génération, par exemple) par GlobalFoundries. Il utilisera de la mémoire vive DDR4 et profitera d’un grand cache à faible latence de type eDRAM (comme certains processeurs Intel actuels). Au niveau communication, les entrées-sorties se feront par PCIe 4.0, les accélérateurs seront connectés par NVLink 2.0 (technologie propriétaire NVIDIA — une version améliorée par rapport aux GPU actuels Pascal) ou CAPI 2.0 (technologie ouverte du consortium OpenPOWER, notamment pour utiliser des FPGA). Chaque processeur aura des parties spécifiques pour la compression et la cryptographie, afin d’accélérer ces parties du traitement (ce qui donne des indications sur les marchés visés, comme les serveurs Web). Les serveurs seront prévus pour accueillir deux de ces processeurs.

Pendant la présentation d’IBM, Google est venu présenter son utilisation de cette architecture, en remplacement des processeurs Intel. Bon nombre de leurs services Web ont migré vers des systèmes POWER, ce qui a été une opération somme toute assez mineure au niveau logiciel pour eux : Google garde ses logiciels indépendants de la plateforme d’exécution, ce qui permet d’effectuer des tests sur d’autres architectures rapidement (comme des processeurs ARM ou POWER).

Google doit garder son matériel toujours à la pointe, afin de rester dans la compétition pour ses différents services et répondre à une demande toujours croissante. Par exemple, sur une dizaine d’années, le nombre de pages Web indexées a été multiplié par un facteur soixante. Depuis 2012, Gmail a vu son nombre d’utilisateurs actifs multiplié par deux ; quand YouTube recevait sept heures de vidéo chaque minute, il doit maintenant en traiter quatre cents chaque minute, à encoder de différentes manières pour les offrir aux visiteurs plus tard.

La société doit en plus limiter ses coûts : la technologie avançant, il est de plus en plus cher de réduire la taille des transistors… et donc d’augmenter la performance fournie pour chaque dollar investi dans l’infrastructure (de la construction à la maintenance). L’architecture POWER semble leur permettre d’atteindre ces objectifs. Google travaille justement avec Rackspace au développement de baies POWER9, sous le nom de Zaius. Intel ne sort pas complètement de leur infrastructure, mais une bonne partie utilise maintenant les processeurs d’IBM, compétitifs avec la solution d’Intel.

Sources : Power9: Google gives Intel a chip-flip migraine, IBM tries to lures big biz (dont l’image), IBM Fires a Shot at Intel with its Latest POWER Roadmap.

Intel concurrence NVIDIA avec son nouveau Xeon Phi Knights Landing

Annoncée il y a de cela un an, la nouvelle mouture des processeurs Intel Xeon Phi, nom de code Knights Landing, était annoncée : ces processeurs sont maintenant livrés aux fournisseurs de matériel HPC. Avec ces nouvelles puces, Intel vise le même segment que NVIDIA avec ses cartes graphiques (GPU) de génération Pascal : l’apprentissage profond, le calcul scientifique de haute performance (HPC).

Actuellement, quatre modèles sont disponibles, avec un nombre de cœurs variable (de soixante-quatre à septante-deux) et des fréquences aussi variables (entre 1,3 et 1,5 GHz), des caractéristiques proches des GPU actuels comme NVIDIA Pascal. Tous sont livrés avec seize gigaoctets de mémoire vive (MCDRAM), empilée et très proche du processeur, pour une bande passante de presque cinq cents gigaoctets par seconde. Ces différentes puces représentent des compromis différents : la plus puissante (7290, 3,46 Tflops) est la plus chère (6294 $), avec un produit bien plus abordable au niveau du téraflops par euro (7210 à 2438 $ pour 2,66 Tflops) ; l’une optimise le ratio performance par watt (7250, 3,05 Tflops pour 215 W, là où le 7290 fournit 3,46 Tflops pour 245 W) et la dernière la mémoire disponible par cœur (7230, soixante-quatre cœurs, comme le 7210, mais la mémoire a une fréquence plus élevée).

Au niveau des chiffres bruts, ces processeurs ne dépassent pas l’offre de NVIDIA : « à peine » trois téraflops et demi pour le plus haut de gamme, quand les GPU NVIDIA Pascal atteignent cinq téraflops (et une bande passante de cinquante pour cent plus élevée, à sept cent vingt gigaoctets par seconde). Par contre, selon les applications, à cause de la différence d’architecture fondamentale, les résultats varient énormément (les Xeon Phi sont organisés comme des processeurs traditionnels : chaque cœur peut exécuter une instruction propre, contrairement aux GPU, où la même instruction est exécutée sur un grand nombre de cœurs). Ainsi, pour de la simulation de dynamique moléculaire, pour le test de performance LAMPPS, un Xeon Phi de milieu de gamme (7250) a fonctionné cinq fois plus vite en consommant huit fois moins de mémoire qu’un GPU NVIDIA K80 (la génération précédant les Pascal). Pour de la visualisation par lancer de rayon, Intel indique être cinq fois plus rapide ; le facteur descend à trois pour de la simulation de risque financier. Ces comparaisons ne sont pas entièrement équitables, à cause de la différence d’âge entre les processeurs, mais donnent la tendance qu’Intel veut montrer. Ces résultats devront être confirmés par des indépendants pour être fiables.

Parmi les tests de performance, Intel s’est aussi orienté vers l’apprentissage profond, branche dans laquelle NVIDIA s’impose actuellement. Ce domaine est actuellement à la pointe de la recherche, avec des résultats de plus en plus intéressants : c’est grâce à des techniques de ce genre que Google a pu battre le joueur le plus fort au monde au jeu de go. Sur un même jeu de test, un Xeon Phi 7250 a obtenu sa réponse en cinquante fois moins de temps qu’un seul processeur traditionnel ; avec quatre tels Xeon Phi, les temps de calcul ont été réduits d’un facteur deux par rapport à quatre GPU NVIDIA K80.

Intel précise également qu’il est plus facile de programmer ses processeurs Xeon Phi : ils embarquent beaucoup plus de cœurs, mais c’est la seule différence avec les processeurs habituels de nos PC, alors qu’il faut réécrire complètement son code (ou utiliser des API adaptées) pour les GPU, avec une phase d’optimisation du code qui nécessite des compétences plus spécifiques. La nouvelle génération de Xeon Phi apporte cependant une distinction plus importante : ces processeurs Intel pourront être utilisés comme processeurs principaux (pas seulement comme cartes d’extension), ce qui évite les opérations de transfert de données, très limitantes pour la performance des applications actuelles. Il reste cependant à déterminer si ces processeurs seront suffisamment rapides pour effectuer toutes les opérations des applications qui leur sont soumises (ils fonctionnent à une fréquence réduite par rapport aux processeurs habituels : ils excellent dans le traitement parallèle, mais pas en série, qui constitue parfois une part importante du code à exécuter).

Ni ces nouveaux Xeon Phi ni les GPU NVIDIA Pascal ne sont actuellement utilisés à grande échelle pour du calcul scientifique. Cependant, ces premiers résultats montrent que les deux jouent dans la même cour. Si les mesures d’Intel se généralisent, ils deviendront un concurrent plus que très sérieux de NVIDIA, notamment dans le marché en expansion de l’apprentissage profond ; s’ils ont en plus l’avantage du prix, la dominance de NVIDIA sera vite mise à mal.

Sources : Intel Takes on NVIDIA with Knights Landing Launch, Intel’s Knights Landing: Fresh x86 Xeon Phi lineup for HPC and AI, Intel Xeon Phi Knights Landing Now Shipping; Omni Path Update, Too.

Merci à Claude Leloup pour sa relecture orthographique.

LLVM lance un nouveau projet : parallel-lib

Il y a trois mois, Google proposait son projet StreamExecutor à LLVM. Cette bibliothèque sert à lancer des calculs sur des processeurs graphiques et d’autres types d’accélérateurs, principalement pour leur solution d’apprentissage profond TensorFlow. L’avantage est de disposer d’un système unique pour lancer des calculs sur ce type d’accélérateur, sans dépendre de la bibliothèque qui sera effectivement utilisée pour les calculs. Cette couche d’abstraction ne fait « que » gérer l’évolution des calculs sur les accélérateurs selon le concept de flux (emprunté à NVIDIA CUDA), d’où le nom de la bibliothèque. Ce projet StreamExecutor s’inscrit notamment dans la lignée d’OpenMP 4, avec la possibilité de décharger une partie du code sur des accélérateurs à l’aide d’une directive spécifique (offload).

Suite à cette proposition de code de la part de Google, après quelques mois de discussions, lancées par la proposition de Google, LLVM lance un nouveau sous-projet orienté programmation concurrente : parallel-libs. Ce projet est présenté comme un parallèle concurrent à compiler-rt, qui rassemble diverses fonctionnalités (implémentation générique d’instructions non disponibles sur certains processeurs, assainisseurs de code, etc.).

En quelques mots, les objectifs de parallel-libs sont plus étendus que ceux de StreamExecutor : ce sous-projet pourra contenir des moteurs d’exécution comme celui d’OpenMP, des bibliothèques d’accès au matériel à l’instar de StreamExecutor, voire des fonctions mathématiques implémentées en parallèle. La seule contrainte pour une inclusion dans parallel-libs est d’être à la croisée des chemins des compilateurs et de l’exécution concurrente, ce qui permettra de partager du code.

Pour le moment, les décisions sont prises, mais le projet n’a pas encore d’existence physique (pas d’emplacement sur le dépôt SVN de LLVM, pas de liste de diffusion). Cela ne devrait pas tarder. D’ailleurs, IBM pourrait rejoindre la danse, avec leurs projets d’interface unique pour lancer du code, que ce soit avec CUDA ou OpenMP, pour lesquels un premier commit est arrivé.

Source : [llvm-dev] parallel-lib: New LLVM Suproject.

L’ordonnanceur de Linux : « une décennie de cœurs perdus »

L’ordonnanceur d’un système d’exploitation est une partie cruciale pour la performance. Il décide de l’affectation des fils d’exécution aux différents cœurs et processeurs d’une machine afin d’utiliser au mieux la machine à disposition, tout en garantissant une certaine réactivité pour les applications qui en ont besoin (notamment les interfaces graphiques : elles ne peuvent pas rester plusieurs minutes sans pouvoir exécuter la moindre instruction, car elles ne peuvent alors pas répondre aux stimuli de l’utilisateur, qui a alors toutes les raisons de râler).

Il y a de cela une quinzaine d’années, Linus Torvalds déclarait, en somme, que l’ordonnancement était un problème très facile et qu’il était déjà très bien résolu dans le noyau Linux depuis dix ans (c’est-à-dire depuis les toutes premières versions du noyau) : inutile d’en discuter, tout fonctionne pour le mieux, tout va très bien, madame la marquise. Linus Torvalds estime même que l’extrapolation de ces techniques aux cas de machines à plusieurs processeurs est « trivial » : une logique de répartition de la charge entre les différents processeurs ne devrait représenter que quelques centaines de lignes de code, que les développeurs « ne devraient pas trop merder », selon ses termes.

Cependant, avec l’avènement de machines avec de plus en plus de cœurs pour le plus grand nombre, l’ordonnancement s’est alors révélé bien plus compliqué que dans le cas à un seul processeur et cœur par machine. En effet, les taux d’utilisation du processeur restent très élevés, tout semble se passer pour le mieux… sauf que certains cœurs restent inutilisés par moments. Au niveau technique, cet ordonnancement reste très similaire à celui pratiqué au début des années 1990, à la différence de la répartition de la charge : régulièrement, le noyau répartit à nouveau les tâches à effectuer sur les différents cœurs, chacun suivant alors une politique équitable entre les tâches (selon l’algorithme CFS, completely fair scheduler).

Une équipe de chercheurs a remarqué des déficiences majeures du côté de l’ordonnanceur en tentant d’expliquer certaines dégradations importantes de performance en laissant le noyau Linux gérer lui-même l’affinité des processus par rapport aux cœurs, plutôt qu’en les assignant manuellement aux cœurs disponibles. De fil en aiguille, ils ont éliminé les causes les plus probables, comme une mauvaise localité en mémoire, des contentieux à l’accès à une ressource partagée ou les changements de contexte. Ils en sont venus à suspecter l’ordonnanceur du noyau. Pour récupérer des informations suffisantes, ils ont développé des outils de suivi à très haute résolution pour caractériser la répartition des tâches aux différents cœurs et processeurs d’une machine de test. Le résultat était sans appel : certains processeurs étaient surchargés, d’autres presque complètement désœuvrés, selon des motifs étranges et difficiles à expliquer rationnellement.

Par la suite, l’équipe a cherché dans le code source du noyau les parties à incriminer, elle a trouvé un premier défaut dans le code de l’ordonnanceur CFS : les chercheurs sont alors partis dans l’exploration plus approfondie du code. Ils ont fini par trouver quatre défauts majeurs dans le code : une fois analysés et corrigés (les patchs sont disponibles sur leur site pour le noyau en version 4.1, ils ne sont pas encore intégré dans Linux), le test de performance de bases de données TPC-H a vu une amélioration de douze à vingt-trois pour cent, le plus flagrant étant probablement une amélioration d’un facteur de cent trente-sept dans certaines charges de type HPC !

Ce travail de détection et de correction doit être très fin, car les techniques conventionnelles de test et de débogage sont totalement inefficaces pour comprendre ce genre de défauts : les symptômes sont très évasifs (les épisodes problématiques sont assez fréquents, mais chacun dure au plus quelques centaines de millisecondes), il est impossible de distinguer un véritable problème du bruit de fond dans un outil comme htop.

En réalité, les problèmes se situent principalement au niveau des heuristiques de CFS : pour éviter des calculs très lourds et de la communication (forcément lente) entre les différents processeurs, certaines données sont approchées à l’aide d’heuristiques (principalement, la charge de chaque cœur et processeur). Cependant, leur impact n’a pas toujours été analysé en profondeur, ce qui laisse une grande marge d’améliorations à ce niveau.

Cet article tire plusieurs conclusions, la première étant que Linus Torvalds est très loin de détenir la vérité quant aux résultats des ordonnanceurs : non, ce n’est pas un problème résolu, il faudra encore pas mal de recherche à ce niveau pour exploiter au mieux le matériel disponible (et éviter de laisser des cœurs totalement inoccupés). Les correctifs proposés par les chercheurs ne résolvent que les problèmes qu’ils ont remarqués : ils ne prétendent pas donner des solutions génériques à tous les problèmes, ils n’ont pas poussé les tests jusqu’à déterminer l’impact sur d’autres types de charges.

L’objectif est atteint : les ordonnanceurs doivent encore évoluer.

Source : The Linux Scheduler: a Decade of Wasted Cores (présentations courte et longue).

Sortie de GCC 6.1 : C++14 activé par défaut, OpenMP 4.5

GCC vient de sortir sa version majeure annuelle, numérotée 6.1. Elle cumule les développements d’une année entière, avec des évolutions dans tous les domaines : côté C++, le compilateur se positionnera sur la norme C++14 par défaut, au lieu de C++98 auparavant, quelques fonctionnalités de C++17 ont été implémentées ; pour le domaine HPC, OpenMP 4.5 est complètement implémenté, les calculs peuvent être déportés sur des coprocesseurs Intel Xeon Phi « Knights Landing » et sur du matériel AMD par HSAIL ; l’implémentation de OpenACC 2.0a a été améliorée, avec une possible déportation sur du matériel NVIDIA par PTX. Au niveau matériel, les prochains processeurs d’AMD, basés sur l’architecture Zen, sont déjà pris en charge ; les plateformes ARM ont été le théâtre de bon nombre d’améliorations ; l’architecture PowerPC a reçu la compatibilité avec POWER9, la prochaine itération des processeurs d’IBM.

Côté C++

La précédente version majeure de GCC, numérotée 5.1, apportait les dernières touches à l’implémentation de C++14, en apportant des fonctionnalités comme la désallocation d’une partie d’un tableau, des constexpr plus généraux, des fonctions anonymes génériques.

Cette nouvelle version de GCC s’arme déjà pour C++17, avec par exemple, la définition d’attributs sur les énumérateurs ou encore des expressions utilisant l’opérateur fold (aussi nommé reduce ou autre, selon les modes) :

// Cette fonction somme tous ses arguments.
template<typename... Args>
  bool f(Args... args) {
    return (true + ... + args);
  }

Plus de détails dans la documentation.

Une nouvelle optimisation en C++ casse du code existant

Une nouvelle optimisation fait parler d’elle : la propagation de valeurs considère désormais que le pointeur this en C++ (qui pointe vers l’objet courant) est toujours initialisé (sa valeur n’est jamais nullptr). Ce point particulier n’a jamais été précisé dans une norme, les compilateurs sont donc libres quant à son interprétation — même si Qt 5 ou Chromium exploitaient l’implémentation précédente. Ce cas peut arriver pour des structures, comme un arbre binaire :

struct Node {
  Node * left;
  Node * right;
};

Pour traverser cet arbre en C, la manière la plus naturelle d’écrire l’algorithme est récursive. Pour traiter le cas d’une branche absente, la fonction commence par vérifier que le pointeur passé en argument est bien valide :

void in_order(Node* n) {
  if (! n) return;
  in_order(n->left);
  in_order(n->right);
}

En C++, la syntaxe est plus plaisante avec une fonction membre. Dans ce cas, l’argument de la fonction est passé de manière implicite, à travers le pointeur this :

void in_order() {
  if (this == nullptr) return;
  left->in_order();
  right->in_order();
}

Cependant, avec cette optimisation (permise par le standard C++), le premier test sera toujours faux, puisque, par hypothèse, this est toujours un pointeur valide… et ce code plantera lamentablement à l’arrivée d’une feuille. Heureusement, cette optimisation peut être désactivée avec un simple paramètre lors de la compilation (-fno-delete-null-pointer-checks) et l’absence de tel code peut aussi être vérifiée (-fsanitize=undefined).

Bien évidemment, une meilleure manière d’écrire le code vérifie directement chacun des deux pointeurs contenus dans la structure avant de continuer la récursion — ce qui évite en passant les problèmes potentiels avec cette optimisation :

void in_order() {
  if (left)   left->in_order();
  if (right) right->in_order();
}

Sources : GCC 6.1 Released, Why does the enhanced GCC 6 optimizer break practical C++ code?, GCC 6 Release Series: Changes, New Features, and Fixes, C++ Standards Support in GCC.
Merci à Winjerome pour ses conseils à la rédaction.

NVIDIA annonce son architecture Pascal et CUDA 8

NVIDIA en parle depuis un certain temps et dégaine, peu après AMD, sa nouvelle générations de processeurs graphiques, dénommée Pascal, un nom qui fait référence à Blaise Pascal, mathématicien et physicien français du XVIIe siècle. Les chiffres bruts donnent déjà le tournis : un tel GPU est composé de dix-huit milliards de transistors (huit milliards pour la génération précédente, Maxwell).

Sur la technique, ce GPU (nommé GP100) est le premier gravé en 16 nm, avec la technologie FinFET+ de TSMC, les précédents l’étaient en 28 nm. Pour un processus aussi récent, la puce est énorme : 610 mm², à comparer au 600 mm² de Maxwell sur un processus bien maîtrisé. Cette surface est utilisée pour les 3840 cœurs de calcul (3072 pour Maxwell), ayant accès à un total de 14 Mo de mémoire cache (6 Mo pour Maxwell). Les cœurs ont aussi augmenté en fréquence : 1,5 GHz au lieu de 1,1 pour Maxwell. Au niveau de la mémoire principale, la technologie HBM2 est utilisée au lieu de la mémoire traditionnelle GDDR5. Une puce Pascal dispose de seize gigaoctets de mémoire (contre douze, il n’y a pas si longtemps, chez Maxwell, maintenant vingt-quatre).

NVIDIA peut donc en profiter pour intégrer bon nombre de nouvelles fonctionnalités, tournées vers le segment HPC, comme sa connectique NVLink. L’une des fonctionnalités très utiles pour monter en performance concerne les nombres à virgule flottante : contrairement à Maxwell, les unités de calcul de Pascal traitent nativement des nombres sur soixante-quatre bits et seize bits ; ainsi, une telle puce peut monter jusque vingt et un mille milliards d’opérations par seconde (21 TFlops) en seize bits, cinq mille milliards en soixante-quatre bits (avec un facteur d’à peu près quatre entre les deux : les unités sur soixante-quatre bits sont grosso modo composées de quatre unités sur seize bits).

Toujours dans le HPC, la mémoire unifiée, entre la mémoire principale de l’ordinateur et celle du processeur graphique, a aussi vu quelques améliorations. Elles se comptent au nombre de deux. Tout d’abord, l’espace d’adressage a été considérablement élargi, ce qui permet d’adresser toute la mémoire centrale et celle du GPU (et non seulement un espace équivalent à la mémoire du GPU). Ensuite, les GPU Pascal gèrent les défauts de page : si un noyau de calcul tente d’accéder à une page mémoire qui n’est pas encore chargée sur le GPU, elle le sera à ce moment-là, elle ne doit plus être copiée dès le lancement des calculs sur le GPU.

L’apprentissage profond, le cheval de bataille de NVIDIA

Toutes ces avancées sont jusque maintenant principalement prévues pour le marché du HPC, plus particulièrement de l’apprentissage de réseaux neuronaux profonds, à l’origine de miracles récents dans le domaine de l’intelligence artificielle.

NVIDIA avance un facteur d’accélération de douze dans un cas d’apprentissage d’un réseau neuronal avec sa nouvelle architecture par rapport à ses meilleurs résultats l’année dernière. Ce facteur est énorme en seulement une année, mais il faut remarquer que la comparaison proposée n’est pas toujours équitable : les nouveaux tests utilisent deux fois plus de GPU que l’année dernière, de nouvelles fonctionnalités ont fait leur apparition sur les GPU spécifiquement pour accélérer ce genre de calculs (les nombres à virgule flottante sur seize bits). Il n’empêche, le résultat reste impressionnant.

Ces avancées réunissent cinq « miracles », selon la terminologie de Jen-Hsun Huang :

  • la nouvelle architecture Pascal ;
  • la technologie de gravure de puces de TSMC ;
  • la nouvelle génération de puces mémoire empilées (HBM2) ;
  • la technologie d’interconnexion entre GPU NVLink ;
  • des améliorations algorithmiques pour tirer parti des progrès précédents.

NVIDIA DGX-1, un supercalculateur dans une boîte

Les tests de performance ont été effectués sur une machine assemblée par NVIDIA, dénommée DGX-1, un monstre de puissance. Elle couple deux processeurs Intel Xeon E5-2698 v3 et huit processeurs NVIDIA Pascal avec 512 Go de mémoire vive et 1,92 To de stockage en SSD. Globalement, la machine peut fournir 170 TFlops pour la modique somme de 129 000 $. NVIDIA la résume comme deux cent cinquante serveurs rassemblés dans un boîtier. Elle est d’ores et déjà en vente, mais les livraisons devraient débuter en juin. Des bibliothèques existantes ont été adaptées pour cette machine pour en tirer le meilleur parti, comme TensorFlow de Google.

CUDA 8 et autres avancées logicielles

Pascal vient avec des améliorations matérielles accessibles par CUDA 8, la nouvelle version de l’API de calcul sur GPU de NVIDIA. Par exemple, les opérations atomiques en mémoire, utiles pour les opérations en parallèle sur une même case mémoire sans risque de corruption, gèrent plus d’opérations sur les entiers (en parallèle avec une implémentation matérielle plus complète). Les développeurs peuvent exploiter une structure d’interconnexion NVLink explicitement depuis CUDA.

Le profilage d’applications est encore amélioré, notamment au niveau de la répartition de la charge entre le CPU et le GPU, pour déterminer les parties où l’optimisation serait la plus bénéfique globalement. Pour ce faire, le profileur visuel montre maintenant les dépendances entre les noyaux de calcul du GPU et les appels à l’API CUDA, afin de faciliter la recherche d’un chemin critique d’exécution.

De nouvelles bibliothèques font également leur apparition au sein de l’écosystème, comme nvGRAPH pour l’analyse de graphes : la planification du chemin d’un robot dans un graphe énorme (comme une voiture dans le réseau routier), l’analyse de grands jeux de données (réseaux sociaux, génomique, etc.). NVIDIA IndeX, une bibliothèque de visualisation de très grands jeux de données (répartis sur plusieurs GPU), est maintenant disponible comme extension à ParaView. cuDNN arrive en version 5, avec d’importantes améliorations de performance.

Sources : Pascal Architecture (images d’illustration), Nvidia Pascal Architecture & GP100 Specs Detailed – Faster CUDA Cores, Higher Thread Throughput, Smarter Scheduler & More, NVIDIA DGX-1 Pascal Based Supercomputer Announced – Features 8 Tesla P100 GPUs With 170 TFLOPs Compute, NVIDIA GTC 2016 Keynote Live Blog (transparents NVIDIA), Inside Pascal: NVIDIA’s Newest Computing Platform, CUDA 8 Features Revealed.

Google envisage de contribuer son StreamExecutor dans LLVM

Google s’intéresse énormément aux différentes plateformes pour effectuer des calculs très intensifs en parallèle, notamment dans le cadre de sa solution libre d’apprentissage profond TensorFlow. La société a développé la bibliothèque StreamExecutor, qui simplifie la gestion des calculs parallèles par rapport aux flux de données, avec une exécution principalement prévue sur des accélérateurs comme des processeurs graphiques (GPU). StreamExecutor se propose comme une couche d’abstraction par rapport à OpenCL et CUDA (les deux technologies prédominantes pour le calcul sur processeurs graphiques), tout en proposant un modèle de traitement des flux similaire à celui de CUDA et une implémentation très proche des meilleures pratiques en C++ moderne. Notamment, cette bibliothèque pourrait être utilisée comme couche de base pour les algorithmes parallèles de la bibliothèque standard de C++17.

L’objectif est en réalité très similaire à celui d’OpenMP, dont les dernières versions permettent de décharger du code sur les accélérateurs. La grande différence est qu’OpenMP est une norme qui a évolué depuis 1997 dans un secteur qui a vu quelques révolutions depuis lors : cette API est très spécialisée et a du mal à bien s’adapter aux accélérateurs actuels. Là où OpenMP génère du code tant pour le processeur principal que l’accélérateur, StreamExecutor ne cherche pas à s’occuper du code qui sera exécuté sur l’accélérateur — le développeur reste responsable de cette partie, afin de l’optimiser au mieux. Grâce à cette différence, StreamExecutor peut ainsi gérer de nouveaux accélérateurs assez facilement.

Google l’a récemment proposé en tant que sous-projet de LLVM, une suite de compilateurs libre. Ainsi, cette bibliothèque pourrait être profondément intégrée au niveau du compilateur, ce qui permettrait une série de tests statiques avant l’exécution de code sur un accélérateur. Notamment, en cas de problème d’arité d’une fonction appelée sur un accélérateur, StreamExecutor détecte le problème et reporte directement une erreur au programmeur (au lieu de ne la détecter que lors d’une tentative d’appel du code concerné).

Les développeurs de LLVM sont relativement partagés concernant cette contribution. Leurs griefs portent principalement sur la concurrence avec liboffload, développée dans le cadre de l’implémentation d’OpenMP pour décharger du code sur des accélérateurs — mais très liée à l’implémentation d’OpenMP. Quand StreamExecutor fonctionne avec des extensions pour CUDA et OpenCL, liboffload peut exécuter du code sur des GPU NVIDIA et des CPU Intel Xeon Phi. En réalité, les deux visent des publics fort différents : liboffload est prévue pour un compilateur, tandis que StreamExecutor se dirige vers tout type d’utilisateur, même si les fonctionnalités se recouvrent. Il n’est cependant pas question à l’heure actuelle d’exploiter cette interface de plus haut niveau pour l’implémentation d’OpenMP.

Source : RFC: Proposing an LLVM subproject for parallelism runtime and support libraries
Voir aussi : la documentation préliminaire de StreamExecutor, TensorFlow.