Babel : introduction à l'optimisation

Introduction

L'optimisation est une étape essentielle dans la vie d'un code de calcul. Celle-ci est malheureusement rarement réalisée proprement, voire jamais entreprise. Le but de ce document est de vous donner une idée de ce que peut vous apporter ce type de travail et de comment procéder. Dans ce domaine, il n'y a pas de recette miracle mais de nombreuses pistes et méthodes de travail peuvent être suggérées.

Que signifie optimiser ?

Optimiser un code de calcul pour un supercalculateur tel que Babel consiste à en réduire ses besoins en ressources. Ces dernières sont diverses mais généralement on parle du temps de restitution. La consommation de mémoire ou d'espace disque entrent également dans cette catégorie.

Pourquoi optimiser ?

Optimiser une application peut vous apporter un certain nombre d'avantages (si vos efforts sont fructueux) :

  • obtention plus rapide des résultats par une diminution du temps de restitution ;
  • possibilité d'obtenir plus de résultats avec les heures qui vous ont été attribuées ;
  • possibilité d'effectuer de plus gros calculs ;
  • meilleure compréhension de votre code, de l'architecture de la machine et de leurs interactions ;
  • avantage compétitif par rapport à d'autres équipes ;
  • découverte et correction de bugs gràce à la relecture des sources du code.

L'amélioration des performances d'une application permet également :

  • une réduction de la consommation d'énergie de vos calculs (les noeuds de calcul de Babel ne consomment presque rien lorsqu'ils ne sont pas utilisés) ;
  • une meilleure utilisation de la machine (le coût d'achat, de maintenance et d'utilisation d'un supercalculateur n'est pas négligeable). Chaque heure qui vous est attribuée représente une dépense pour toute la communauté scientifique ;
  • de libérer des ressources pour d'autres groupes de recherche.

Pourquoi ne pas optimiser ?

Optimiser n'est pas toujours la meilleure stratégie. Tout code de calcul ne nécessite pas d'être optimisé (rarement vrai pour des machines massivement parallèles) ou les avantages/gains peuvent être insuffisants par rapport à l'effort à fournir.

On peut citer comme raisons pour ne pas optimiser :

  • insuffisance de ressources ou moyens pour le faire (manque de personnel, temps, compétences,…). L'IDRIS peut vous aider en cela ;
  • diminution de la portabilité du code (beaucoup d'optimisations sont spécifiques à l'architecture de la machine) ;
  • risque de pertes de performances sur d'autres machines ;
  • diminution de la lisibilité des sources et maintenance plus délicate ;
  • risque d'introduction de bugs ;
  • code non pérenne ;
  • code suffisamment rapide (il ne sert à rien d'optimiser un code qui fournit déjà des résultats dans un temps raisonnable) ;
  • code déjà optimisé.

Certaines personnes préfèrent également attendre que les machines évoluent. Un calculateur plus rapide permet un gain en performances sans efforts. Ce raisonnement est de moins en moins vrai car la tendance actuelle est vers un parallélisme de plus en plus massif avec des coeurs à peine plus rapides. De plus, les performances pour les entrées/sorties croissent beaucoup moins vite que les puissances de calcul. Sans oublier que la durée de vie d'un supercalculateur est de plusieurs années ; il s'agit donc d'être patient.

Quand optimiser ?

Une application ne doit être optimisée que lorsqu'elle fonctionne correctement. Il ne faut jamais commencer ce travail (hormis pour le choix des algorithmes) trop tôt. En effet, le risque est grand que vous ajoutiez des bogues supplémentaires, réduisiez fortement la lisibilité et la compréhension du code et optimisiez des procédures qui seront abandonnées ou ne seront pas ou très peu utilisées ou qui seront totalement réécrites. Le danger est également que vous passiez beaucoup de temps à optimiser des parties de code qui consomment de toute façon très peu de ressources (passer 3 jours pour gagner un facteur 2 dans un sous-programme représentant 0,001% du temps d'exécution n'est pas très productif).

Il ne faut se lancer dans l'optimisation que si vous estimez que votre application est trop lente ou ne permet pas de faire tourner vos gros calculs dans un temps raisonnable. Si vous êtes pleinement satisfait de votre application, l'investissement n'est peut être pas nécessaire.

N'oubliez pas non plus qu'avant de vous lancer dans cette démarche, vous avez besoin de temps. Optimiser un code de calcul n'est pas une tâche aisée et prend beaucoup de temps (généralement beaucoup plus qu'estimé surtout si vous n'êtes pas expérimenté). Si vous avez de nombreuses autres contraintes, ne vous lancez pas ! Il vaut mieux obtenir des résultats même s'il faut patienter un peu que de commencer à optimiser un code et ne plus avoir le temps de faire vos calculs.

Comment optimiser ? Méthodologie conseillée

Le profilage

Une fois que avez décidé d'optimiser votre application, ne commencez pas à modifier vos sources. Avant de commencer, il est absolument nécessaire de déterminer où l'effort doit être porté. Il faut identifier les parties critiques de votre application qui nécessitent des améliorations. La plupart du temps, les sections du code consommant le plus de ressources ne sont pas celles que l'on pense. Le profilage permet de vérifier (et souvent d'invalider) vos hypothèses à ce propos.

Le profilage d'une application consiste donc en la détermination des parties qui utilisent le plus de ressources. Il faut bien être attentif à le faire sur un jeu de données caractéristique de ce que vous souhaitez calculer. Essayez de vous approcher le plus possible des conditions réelles pour obtenir un profil réaliste. Un certain nombre d'outils sont disponibles sur Babel et sont décrits dans les pages pointées ci-après :

L'optimisation

Une fois le profilage effectué et les zones les plus consommatrices mises en évidence, l'optimisation proprement dite pourra commencer. Il faudra évidement s'attaquer d'abord aux zones les plus gourmandes en ressources car c'est là que se trouvent potentiellement les plus gros gains. Il ne sert pas à grand chose de travailler sur les parties peu consommatrices, d'autant plus que votre temps est précieux.

L'optimisation peut se faire dans 3 domaines différents. Les liens qui suivent les détaillent :

Il est très important de vérifier systématiquement que les modifications apportées ne changent pas les résultats obtenus. Il est en effet déjà très facile d'introduire des bogues lorsque vous programmez couramment ; c'est encore plus vrai dans les phases d'optimisation.

N'oubliez pas non plus de vous assurer qu'il y ait bien une amélioration des performances. Il n'est pas rare que les modifications faites produisent l'effet inverse. Très souvent, on observe des pertes ou des gains nuls. Cela est généralement dû au fait que vous compliquiez le travail d'optimisation du compilateur ou à une mauvaise compréhension de l'effet attendu.

Dans le cas où les gains sont faibles, il faut se poser la question de l'intérêt de garder le nouveau code surtout si la lisibilité s'en ressent. Il ne faut pas hésiter à revenir à la solution initiale pour garder une application maintenable.

Que fournit l'IDRIS ?

En plus de la documentation sur notre serveur web, nous fournissons des moyens pour vous aider :

  • des formations sur la Blue Gene/P (cours ''Utilisation Babel'') sont données. Bien que non axées sur l'optimisation, une description détaillée de l'architecture et de nombreux conseils y sont donnés. Une bonne compréhension du fonctionnement de Babel est indispensable pour pouvoir obtenir des gains significatifs ;
  • pour des besoins ponctuels, le support utilisateurs peut répondre à vos questions par email ()ou par téléphone au 01.69.35.85.55 ;
  • pour des demandes importantes, un service de support avancé peut être fourni.