OpenHMPPLe Standard Ouvert OpenHMPP (HMPP pour Hybrid Multicore Parallel Programming) est un modèle de programmation basé sur un jeu de directives, conçu pour manipuler les accélérateurs matériels sans se soucier de la complexité associée à la programmation GPU. Le choix d’implémentation concernant ce modèle s’est porté sur les directives car elles permettent une relation déliée entre le code de l’application et l’utilisation des accélérateurs matériels. NB : Cet article porte sur les directives OpenHMPP qui constituent l'Open Standard, mais ne traite pas de l'exécution des directives, liée à l'implémentation des directives. IntroductionLa syntaxe offerte par le modèle OpenHMPP permet de répartir efficacement les calculs sur les accélérateurs matériels et d’optimiser les mouvements de données de/vers la mémoire du matériel. Le modèle est basé sur le projet CAPS (Compiler and Architecture for Embedded and Superscalar Processors) mené en commun par l'INRIA, le CNRS, l'Université de Rennes 1 et l'INSA de Rennes. Le concept du standard OpenHMPPLe standard OpenHMPP est basé sur le concept de codelet, qui est une fonction qui peut être exécutée à distance sur le matériel. Le concept de codeletUn codelet a les propriétés suivantes :
Ces propriétés permettent de s'assurer qu'un codelet RPC peut être exécuté à distance par un matériel. Cet appel RPC et ses transferts de données associés peuvent être asynchrones. L'exécution RPC d'un codeletOpenHMPP fournit un protocole d'appel de procédures à distance synchrone et asynchrone. L'implémentation d'opération asynchrone est dépendante du matériel. Le modèle de mémoire mis en œuvreOpenHMPP prend en compte deux espaces d'adressage :
Les directives HMPPLes directives OpenHMPP peuvent être vues comme des “méta-informations” que l’on ajoute dans le code source de l’application. Ce sont donc des méta-informations inoffensives, c’est-à-dire qu’elle ne changent pas le comportement original du code. Elles adressent l’exécution à distance (RPC) de la fonction ainsi que les transferts de données de/vers la mémoire du matériel. Le tableau qui suit introduit les directives OpenHMPP, classées selon le besoin adressé : certaines sont destinées à des déclarations, d’autres sont destinées à la gestion de l’exécution.
Concept de jeu de directivesL’un des points fondamentaux de l’approche proposée par le modèle OpenHMPP est le concept de directives, associées à des labels, qui rendent possible la mise en place d’une structure cohérente pour un jeu de directives entier, disséminé dans l’application. Il existe deux types de labels :
Syntaxe des directives OpenHMPPDans le but de simplifier les notations, les expressions régulières seront utilisées pour décrire la syntaxe des directives OpenHMPP. Les conventions de couleurs suivantes seront également utilisées :
Syntaxe généraleLa syntaxe générale des directives OpenHMPP est :
#pragma hmpp <grp_label> [codelet_label]? directive_type [,directive_parameters]* [&]
!$hmpp <grp_label> [codelet_label]? directive_type [,directive_parameters]* [&]
où :
Paramètres des directivesLes paramètres associés à une directive peuvent avoir plusieurs types. À suivre, les paramètres définis avec OpenHMPP :
Les directives OpenHMPPDéclaration et exécution d'un codeletUne directive Pour la directive
La syntaxe de la directive est: #pragma hmpp <grp_label> codelet_label codelet [, version = major.minor[.micro]?]? [, args[arg_items].io=[[in|out|inout]]* [, args[arg_items].size={dimsize[,dimsize]*}]* [, args[arg_items].const=true]* [, cond = "expr"] [, target=target_name[:target_name]*] Il est possible d'avoir plusieurs directives La directive La syntaxe de la directive est: #pragma hmpp <grp_label> codelet_label callsite [, asynchronous]? [, args[arg_items].size={dimsize[,dimsize]*}]* [, args[arg_items].advancedload=[[true|false]]* [, args[arg_items].addr="expr"]* [, args[arg_items].noupdate=true]* Un exemple à suivre :
Dans certains cas, une gestion spécifique des données est nécessaire dans l'application (optimisation des mouvements de données entre CPU et GPU, variables partagées…). La directive La syntaxe de la directive est: #pragma hmpp <grp_label> group [, version = <major>.<minor>[.<micro>]?]? [, target = target_name[:target_name]*]? [, cond = “expr”]? Directives appliquées aux transferts de données (optimisation des surcoûts liés aux communications)Le principal goulet d'étranglement lors de l'utilisation du HWA réside souvent dans les transferts de données entre le matériel et le processeur principal. Pour limiter les surcoûts liés aux communications, les transferts de données peuvent être communes à des exécutions successives d'un même codelet en utilisant la propriété asynchrone du matériel.
Elle verrouille le matériel et alloue la quantité de mémoire nécessaire. #pragma hmpp <grp_label> allocate [,args[arg_items].size={dimsize[,dimsize]*}]*
Elle spécifie à quel moment le matériel doit être libéré pour un groupe ou pour un codelet autonome. #pragma hmpp <grp_label> release
Elle charge les données avant l'exécution à distance du codelet. #pragma hmpp <grp_label> [codelet_label]? advancedload ,args[arg_items] [,args[arg_items].size={dimsize[,dimsize]*}]* [,args[arg_items].addr="expr"]* [,args[arg_items].section={[subscript_triplet,]+}]* [,asynchronous]
Elle constitue une barrière synchrone qui permet d'attendre la complétion de l'exécution d'un codelet asynchrone puis avant de télécharger les résultats. #pragma hmpp <grp_label> [codelet_label]? delegatedstore ,args[arg_items] [,args[arg_items].addr="expr"]* [,args[arg_items].section={[subscript_triplet,]+}]*
La directive #pragma hmpp <grp_label> codelet_label synchronize
Dans l'exemple qui suit, l'initialisation du matériel, l'allocation de la mémoire et le téléchargement des données d'entrée sont effectués une seule fois, en dehors de la boucle au lieu d'être effectués à chaque itération de la boucle.
Partage de données entre codeletsCes directives permettent de partager tous les arguments ayant le même nom pour tout un groupe. Les types et dimensions de tous les arguments partagés doivent être identiques. La directive #pragma hmpp <grp_label> map, args[arg_items] La directive La notation est la suivante : #pragma hmpp <grp_label> mapbyname [,variableName]+ Variable globaleLa directive Ces variables peuvent être directement accédées à partir de n'importe quel codelet du groupe sur le matériel (elles sont en quelque sorte considérées comme "résidentes" sur le matériel). Cette directive s'applique à la déclaration qui la suit dans le code source. La syntaxe de cette directive est : #pragma hmpp <grp_label> resident [, args[::var_name].io=[[in|out|inout]]* [, args[::var_name].size={dimsize[,dimsize]*}]* [, args[::var_name].addr="expr"]* [, args[::var_name].const=true]* La notation Accélération de régionUne région est un mélange des directives codelet/callsite. Son but est d'éviter la restructuration du code imposée par la création explicite des codelets. Par conséquent, tous les attributs disponibles pour les directives La syntaxe est la suivante : #pragma hmpp [<MyGroup>] [label] region [, args[arg_items].io=[[in|out|inout]]* [, cond = "expr"]< [, args[arg_items].const=true]* [, target=target_name[:target_name]*] [, args[arg_items].size={dimsize[,dimsize]*}]* [, args[arg_items].advancedload=[[true|false]]* [, args[arg_items].addr="expr"]* [, args[arg_items].noupdate=true]* [, asynchronous]? [, private=[arg_items]]* { C BLOCK STATEMENTS } ImplémentationsOpenHMPP est basé sur la version 2.3 de HMPP (, CAPS entreprise). Le modèle proposé par OpenHMPP est implémenté par :
De plus, OpenHMPP est utilisé dans le cadre de projet HPC mené dans des domaines tels que le pétrole, l'énergie, l'industrie, l'éducation et la recherche et permet de développer des versions hautes performances de leurs applications, tout en préservant le code déjà produit. Voir aussiRéférences
|