Brevet FR2938091A1 — publié le 20100507

Procédé de réalisation d'un appel d'une instance d'une fonction, dispositif, et programme d'ordinateur correspondant. 1 DOMAINE DE L'INVENTION La présente invention se rapporte au domaine du déploiement d'applications logicielles. La présente invention se rapporte plus particulièrement à l'appel de fonction dans des applications informatiques destinées à être exécutées sur des plateformes matérielles qui ne sont pas homogènes. Une plateforme matérielle, telle qu'un ordinateur personnel de type PC, est composée de nombreux éléments : un ou plusieurs processeurs, une ou plusieurs carte graphique, des bus de liaisons de données (bus local série, bus parallèle), des interfaces de gestion de la mémoire volatile (RAM) ainsi que des interfaces de gestion de la mémoire de masse. Bien que respectant des techniques de communications sensiblement identiques, de telles plateformes matérielles peuvent être profondément différentes. De manière générale, des applications informatiques, mises en oeuvre par un code (ou programme) applicatif, requièrent des puissances de calculs de plus en plus importante afin d'apporter à l'utilisateur rapidité et fonctionnalités. Ces codes mettent en oeuvre des algorithmes qui mélangent des phases de calculs séquentiels et parallèles de complexité diverse. L'utilisation des architectures multicoeurs, que l'on retrouve dans de très nombreuses plateformes matérielles, est fondée sur l'exploitation des phases parallèles de calculs des codes applicatifs. Ces codes se doivent d'utiliser au mieux les ressources matérielles (composants, carte graphique, processeurs et mémoire) de la manière la plus efficace et ce quelques soit l'architecture de la plateforme matérielle en question. De plus, chaque application doit prendre en compte les ressources utilisées par les autres applications afin de ne pas créer une compétition dommageable aux performances globales du système. Dans la suite nous dénommons � noeud de calcul � un ensemble de processeurs multicoeurs hétérogènes ou homogènes organisés autour d'une mémoire principale. Cette mémoire n'est pas nécessairement partagée par l'ensemble des processeurs, les transferts de données peuvent aussi être mis en oeuvre par DMA (de l'anglais � Direct Memory Access � pour � Accès Direct en Mémoire �) etc. Chaque coeur de calcul peut disposer d'une mémoire locale qui lui est propre, comme cela est le cas dans certaines architectures multicoeurs. 2 SOLUTIONS DE L'ART ANTERIEUR Dans l'état actuel des techniques, La performance d'une application est influencée par un nombre important de facteurs : - les éléments matériels disponibles sur le noeud de calculs : - un noeud de calcul est l'ensemble des processeurs -multicoeurs ou pas- et les accélérateurs matériels : par exemple GPU, (� Graphie Processing Unnit �) ou FPGA, (Field Programmable Gate Arrays ou � réseaux logiques programmables �) se partageant une mémoire physique commune ; - la priorité éventuelle donnée à chaque application ; les jeux de données sur lesquelles les applications travaillent ; - les applications déjà en cours d'exécution et l'utilisation des ressources par celle-ci. Dans la suite, de tels facteurs sont regroupés sous l'expression � contexte d'exécution �. De nombreuses techniques, notamment basées sur l'utilisation en parallèle des processeurs des architectures multicoeurs, visent à répondre à de telles problématiques. Leur objectif est d'offrir une des performances maximum en utilisant au mieux les ressources disponibles. Les difficultés rencontrées viennent, comme cela a été évoqué, de la multitude de composants différents qui peuvent composer une plateforme et du fait que l'utilisation optimum de ces composants n'est pas aisée. Pour augmenter les performances, des techniques de compilation d'applications logicielles ont été proposées. Elles mettent en oeuvre deux grands principes : une adaptation statique permettant de conformer l'application à la plateforme sur laquelle elle est installée. Cette adaptation statique peut être réalisée au moment de l'installation du logiciel sur la plateforme. Ainsi, lors de l'installation de l'application sur l'ordinateur, le composant logiciel chargé de l'installation obtient un certain nombre de paramètre de l'ordinateur et effectue une compilation, d'au moins certains composants de l'application en fonction de ces paramètres. Par exemple, si le composant d'installation a détecté que la plateforme dispose d'une carte graphique d'un certain type, ou d'une certaine marque (NVidiaTM ou ATITM par exemple), cette information est transmise au compilateur qui réalise une compilation des fonctions et procédures utilisant la carte graphique en fonction de ces paramètres (type de processeur graphique, mémoire disponible sur la carte, etc.). Cette technique de compilation à l'installation, lors du déploiement, présente l'avantage de fournir un ensemble d'instances de fonctions ou d'instances de procédures compilées en fonction de la plateforme sur laquelle l'application est installée, et donc adaptées à fonctionner avec les composants de cette plateforme. Elle présente l'inconvénient de ne pas prendre en compte les paramètres de l'exécution de l'application : lors de l'exécution de l'application si la carte graphique est surchargée et qu'elle n'est pas à même de réaliser le traitement demandé, le fait que l'instance de la fonction qui doit réaliser le traitement est adaptée au composant ne change rien au fait que les performances de l'application sont dégradées, au moins le temps que la carte graphique soit déchargée. En d'autres termes, cette technique ne prend pas en compte l'intégralité du contexte d'exécution de l'application. Une autre technique consiste à réaliser une compilation des fonctions ou procédures en fonction du besoin pour générer des instances de fonctions ou de procédures au moins partiellement adaptée au contexte d'exécution. Ces techniques permettent de créer l'instance de la fonction au moment de l'appel de celle-ci. Cette technique est appelée JIT (de l'anglais � Just In Time � pour � Juste à temps �). Elle est également appelée compilation à la volée. Lors de l'exécution de l'application, si une fonction doit être appelée, on vérifie si cette dernière a déjà été compilée et s'il existe une instance de fonction qui peut être utilisée. Si ce n'est pas le cas, on réalise une compilation à la volée en fonction de paramètres récupérés dynamiquement pour créer une instance de fonction exécutable. Ce type de technique JIT est idéal lors d'opérations de débogage d'applications et pour la génération de code en fonction du contexte (pile d'appel, mais indépendamment de l'occupation des ressources matérielles) de l'appel de la fonction qui est compilée à la volée. . La compilation à la volée n'est cependant pas une technique utilisable, en l'état, pour des applications temps réel demandant des ressources importantes à la plateforme sur laquelle elle s'exécute. En effet, bien que le code source d'origine de la fonction à compiler ne soit pas directement employé pour la compilation (la compilation à la volée utilise un code intermédiaire qui a fait l'objet d'une précompilation et d'optimisation de manière statique), la phase de compilation JIT est tout de même consommatrice de temps, de sorte que la phase de compilation à la volée n'aura pas pour effet de réduire le temps d'exécutuion. Elle aura même l'effet inverse, c'est-à-dire qu'elle consommera plus de temps d'exécution que si une fonction déjà compilée avait été utilisée. 3 RESUME DE L'INVENTION L'invention permet de pallier ces inconvénients de l'art antérieur. En effet, l'invention concerne un procédé de réalisation d'un appel d'une instance d'une fonction présente au sein d'au moins un premier module logiciel et requise par un second module logiciel, dit module logiciel appelant. Selon l'invention, un tel procédé comprend : - une étape d'obtention d'un contexte d'exécution courant, ledit contexte d'exécution courant dépend d'au moins une situation d'exécution dudit module logiciel appelant et comprend des données d'exécution ; - une étape de sélection de ladite instance de fonction, parmi au moins deux instances disponibles, en fonction desdites données d'exécution dudit contexte d'exécution courant. Ainsi, l'invention permet de résoudre les problèmes liés à la prise en compte de multiples architectures logicielles en sélectionnant, au moment de l'exécution du module logiciel appelant, l'instance d'une fonction qui est la mieux à même de fournir des résultats plus rapidement. Le module logiciel appelant peut par exemple être l'application principale en cours d'exécution, tandis que le premier module logiciel peut être une bibliothèque de liaison dynamique ou une librairie chargée dynamiquement au début de l'exécution de l'application. Selon un mode de réalisation particulier de l'invention, ladite étape de sélection de ladite instance de fonction comprend : - une étape de chargement, au sein d'un environnement d'exécution dudit module logiciel appelant, d'une structure de données préalablement construite associée à ladite fonction et à une pluralité de contexte d'exécution ; - une étape de recherche, au sien de ladite structure de données, d'une référence à ladite instance de fonction à sélectionner en fonction desdites données d'exécution dudit contexte d'exécution courant, délivrant un identifiant d'instance ; - une étape d'identification, parmi lesdites au moins deux instances dudit premier module logiciel, de ladite instance de fonction à sélectionner à l'aide dudit identifiant d'instance. Ainsi, l'invention permet de réaliser une identification d'une instance de fonction à appeler en fonction d'une structure de données, qui a fait l'objet d'une construction préalable. Cette construction préalable consiste en la création de la structure de données en fonction de contextes d'exécution préalablement déterminés. Ces contextes d'exécution prédéterminés servent ensuite durant l'exécution du module logiciel appelant, pour déterminer qu'elle est l'instance de la fonction à laquelle il convient de faire appel. Selon un mode de réalisation particulier de l'invention, ladite étape de sélection comprend en outre, lorsque ladite de recherche est infructueuse, une étape de sélection d'une instance d'appel par défaut. Ainsi, l'invention permet de pallier l'absence d'un contexte dans la structure de données associée à ladite fonction. Ainsi, lorsque le contexte courant d'exécution de la fonction ne correspond pas à un contexte précalculé, une instance de fonction par défaut peut être mise en oeuvre pour permettre à l'application de se poursuivre malgré tout. Cette instance par défaut peut ne pas être la meilleure instance en termes de performances par rapport au contexte d'exécution, mais elle assure que l'application se déroule sans erreur. Selon une caractéristique particulière de l'invention, ledit contexte d'exécution courant comprend en outre des données relatives à : - une architecture matérielle d'une plateforme matérielle sur laquelle ledit module logiciel appelant s'exécute ; - une charge de travail courante de ladite plateforme matérielle sur laquelle ledit module logiciel appelant s'exécute. Ainsi, l'invention permet de prendre en compte de multiple situation d'exécution pour déterminer de manière optimale le contexte courant d'exécution et de ce fait sélectionner l'instance de la fonction qui sera le mieux à même de correspondre au contexte d'exécution courant. Selon une caractéristique particulière de l'invention, ledit contexte d'exécution courant est matérialisé sous la forme de données d'exécution dépendantes dudit module logiciel appelant et de ladite plateforme matérielle sur laquelle ledit module logiciel appelant s'exécute. Selon une caractéristique particulière de l'invention, ladite d'au moins une situation d'exécution dudit module logiciel appelant comprend une taille de problème (n), ladite taille de problème (n) étant un paramètre de ladite instance de fonction sélectionnée. Ainsi, l'invention permet de sélectionner l'instance de fonction à appeler en fonction du problème à résoudre par la fonction. En d'autre terme, l'invention rend possible la sélection d'une instance en fonction du paramètre d'appel de cette fonction. Pour illustrer cette caractéristique, on suppose une fonction dont le paramètre est un entier � i �. Le contexte d'exécution intégrera la valeur de cet entier � i � de sorte que par exemple, si la valeur de � i � est inférieure à mille, une première instance de fonction sera appelée et si la valeur de � i � est supérieure ou égale à mille et inférieure ou égale à deux mille, une deuxième instance de fonction sera appelée. Si la valeur de � i � est supérieure à deux mille, une instance d'appel par défaut peut être mise en oeuvre. La taille du problème n'est cependant pas limitée à cet exemple particulier. Le problème par exemple peut se présenter sous la forme d'un ensemble de paramètres, par exemple sous la forme d'un tableau. La sélection d'une instance particulière peut alors être réalisée en fonction de la taille des différents problèmes des paramètres ou de la taille globale de l'ensemble de paramètres. Selon un mode de réalisation particulier de l'invention, ladite structure de données se présente sous la forme d'un arbre de décision, dans lequel chaque noeud dudit arbre de décision correspond à une décision à prendre en fonction d'au moins une desdites données d'exécution dudit contexte d'exécution courant. Selon une caractéristique particulière de l'invention, les feuilles dudit arbre de décision comprennent au moins un identifiant d'instance de fonction à appeler. Ainsi, à l'issue du parcours de l'arbre, lors de l'étape de recherche de l'instance de fonction la plus appropriée à être exécutée, un identifiant d'instance de fonction est trouvé pour indiquer au module logiciel appelant (l'application), qu'elle est l'instance de la fonction qu'il convient d'utiliser Selon une caractéristique particulière de l'invention, lorsqu'une feuille dudit arbre de décision ne comprend pas d'identifiant d'instance de fonction à appeler, ledit procédé comprend une étape de sélection d'une instance de fonction utilisée par défaut. Selon une caractéristique particulière de l'invention, lorsqu'une feuille dudit arbre de décision ne comprend pas d'identifiant d'instance de fonction à appeler, ledit procédé comprend une étape de compilation dynamique d'une instance de fonction à utiliser en fonction d'au moins certaines données dudit contexte d'exécution courant. Ainsi, l'invention permet de pallier efficacement l'absence d'instance de fonction adaptée au contexte d'exécution courant en compilant, lors de l'exécution du module logiciel appelant, une instance de fonction. On note que, à la différence des technique des l'art antérieures pour lesquelles cette compilation juste à temps est réalisée quelque soit le contexte d'exécution courant de l'application, l'invention permet d'augmenter les performances générales de l'application de façon drastique car cette étape de compilation dynamique (également appelée � JIT �, de l'anglais � Just In Time �) n'est mise ne oeuvre qu'en dernier recours, lorsque l'arbre de décision n'a pas permis d'identifier une instance de fonction convenable. Selon un autre aspect, l'invention concerne également un procédé de calcul d'un arbre de décision. Selon l'invention, un tel procédé permet d'obtenir un arbre de décision qui est par la suite utilisé dans un procédé de réalisation d'un appel d'une instance de fonction tel que décrit précédemment. Selon un autre aspect, l'invention concerne également un procédé de construction d'une structure de données de sélection d'une instance de fonction à appeler lorsqu'un premier module logiciel, dit module logiciel appelant, requiert l'exécution d'une fonction auprès d'un second module logiciel. Selon l'invention, ledit procédé de construction comprend, pour une fonction donnée : - une étape de compilation d'une pluralité d'instances de fonction, chaque instance étant configurée pour présenter une performance probable en fonction d'au moins un contexte d'exécution déterminé ; - une étape d'analyse de la performance réelle desdites instances de ladite pluralité d'instance de fonctions délivrant des indices de performances ; - une étape de construction de ladite structure de données associant un identifiant d'instance de fonction à un ensemble de données d'un contexte d'exécution de sorte que ladite structure de décision permettent de décider de l'instance de fonction à appeler en fonction desdits indices de performances délivrés. Selon un autre aspect, l'invention concerne encore un dispositif de réalisation d'un appel d'une instance d'une fonction présente au sein d'au moins un premier module logiciel et requise par un second module logiciel, dit module logiciel appelant, Selon l'invention, un tel dispositif comprend : - des moyens d'obtention d'un contexte d'exécution courant, ledit contexte d'exécution courant dépend d'au moins une situation d'exécution dudit module logiciel appelant et comprend des données d'exécution ; - des moyens de sélection de ladite instance de fonction, parmi au moins deux instances disponibles, en fonction desdites données d'exécution dudit contexte d'exécution courant. L'invention concerne également un ou plusieurs programmes d'ordinateur comportant des instructions pour la mise en œuvre d'un de réalisation d'un appel d'une instance de fonction et/ou d'un procédé de construction respectivement, tels que décrits précédemment. Par exemple, de tels programmes sont téléchargeables depuis un réseau de communication et/ou stockés sur un support lisible par ordinateur et/ou exécutables par un processeur. 4 LISTE DES FIGURES D'autres caractéristiques et avantages de l'invention apparaîtront plus clairement à la lecture de la description suivante d'un mode de réalisation préférentiel, donné à titre de simple exemple illustratif et non limitatif, et des dessins annexés, parmi lesquels : la figure 1 présente le principe général de l'invention ; - la figure 2 présente un arbre de décision selon l'invention ; la figure 3 illustre le processus de création d'un arbre de décision selon l'invention. 5 DESCRIPTION DETAILLEE DE L'INVENTION 5.1 Rani rp incipe de l'invention Comme cela a déjà été présenté, l'efficacité d'exécution d'une application dépend fortement des décisions prises à l'exécution qui guide le choix des ressources à utiliser et de la version de code qui utilisera ces ressources. Ces décisions sont complexes car elles font entrer un grand nombre de paramètres. En d'autres termes les décisions si l'on cherche à calculer la décision (ou le mécanisme de décision) à l'exécution, cela est très couteux en temps et ressources matérielles. Par exemple, on ne peut pas demander à un compilateur JIT de produire des versions de code pour un processeur graphique (GPU), un processeur monocoeur, un bicoeur et ensuite de sélectionner la meilleure version en fonction du contexte, car une telle solution est inefficace car beaucoup plus gourmande en temps d'exécution. Afin de guider l'exécution d'une application en fonction du contexte d'exécution courant (la situation dans laquelle se trouve l'application par rapport à la plateforme ainsi que les paramètres nécessaires à l'exécution de la fonction), l'invention met en oeuvre des structures de données pré-calculés qui sont intégrées dans un exécutif qui instancie la décision à l'exécution d'une application. L'instanciation de la décision consiste à décider qu'elle est l'instance de la fonction que l'on utilise pour augmenter les performances. La décision d'utiliser une instance plutôt qu'une autre est donc réalisée à l'exécution. Il s'agit bien, selon l'invention, d'une instance différente d'une même fonction : si une fonction rend un résultat � r �, ce résultat � r � sera rendu à l'identique par toutes les instances de ces fonctions. Seules les performances pour fournir ce résultat seront différentes d'une instance à l'autre. L'objet de l'invention n'est pas de décider, à l'exécution, d'utiliser une fonction plutôt qu'une autre, mais bien une instance différente d'une même fonction, qui se différencie par les ressources matérielles utilisées et leur temps d'exécution. On rappelle qu'une instance, selon l'invention, est une version d'une fonction, se présentant sous une forme exécutable, permettant de fournir un résultat en fonction d'un ensemble de paramètres d'entrée. Cet ensemble de paramètre peut être vide. Une fonction est un est un ensemble d'instructions, rédigées dans un langage de programmation, réalisant une certaine tâche et fournissant un résultat. Une fonction qui ne renvoie aucun résultat est une procédure. Pour plus de commodité, le terme fonction (et également le terme codelet par la suite) est utilisé pour désigner à la fois des fonctions et des procédures. Selon l'invention, on utilise une structure de données pour décider de l'instance de fonction à utiliser, au moment de l'exécution de l'application. Cette structure de données utilise un contexte d'exécution courant (également appelé contexte d'appel courant) pour identifier une instance de fonction à utiliser. Le contexte d'exécution comprend plus de paramètres et de données que les données nécessaires à l'exécution de l'instance de fonction. Ainsi, ce n'est pas seulement les données d'entrée de l'instance de la fonction qui servent à déterminer l'instance à utiliser. Les données d'entrée de l'instance de la fonction peuvent être appelées � problème � et ce problème peut avoir une taille. On verra par la suite qui la décision d'utiliser telle ou telle instance peut dépendre de la taille du problème (comme par exemple la longueur des paramètres d'entrée). L'invention porte ainsi sur un procédé de réalisation d'un appel d'une instance d'une fonction (première, deuxième ou nième instance) présente au sein d'au moins un premier module logiciel (par exemple une bibliothèque qui contient les instances) et requise par un second module logiciel, dit module logiciel appelant (l'application). Selon l'invention, ce procédé comprend : - une étape d'obtention d'un contexte d'exécution courant, qui dépend d'au moins une situation d'exécution dudit module logiciel appelant (c'est le contexte logiciel d'appel) et comprend des données d'exécution ; - une étape de sélection de ladite instance de fonction, parmi au moins deux instances disponibles, en fonction du contexte d'exécution courant. Dans de nombreux cas, le premier module logiciel et le deuxième module logiciel seront compris au sein de l'application, de sorte que l'application contiendra les instances de fonctions : le premier et le deuxième module logiciels sont chargé au démarrage et sont accessibles à partir de l'exécutif. La sélection de l'instance à utiliser est, selon l'invention, réalisée lors de l'exécution de l'application et non pas préalablement lors de la compilation de l'application. La solution de l'invention est donc adaptative dans la mesure où les décisions d'exécution ne sont pas figées à la compilation de l'application ou en fonction de choix d'architectures. L'invention permet par exemple dans un cas d'exécuter une fonction sur le processeur central de la plateforme (le processeur multicoeurs par exemple en utilisant l'instance appropriée) et dans un autre cas, un peu plus tard au cours de l'exécution de l'application sur la carte graphique (en utilisant l'instance appropriée à l'exécution sur la carte graphique). Selon l'invention, il est également possible, dans le cas ou la structure de données ne délivre pas un identifiant d'instance à utiliser, par exemple si les données du contexte d'exécution courant ne se prêtent pas à l'identification d'une instance, de sélectionner une instance dite par défaut pour permettre la continuation de l'exécution. Dans un autre mode de réalisation, il peut être astucieusement prévu de combiner l'approche de l'invention à une compilation à la volée en cas d'absence d'instance de fonction disponible pour un contexte d'exécution courant. Ainsi, selon ce mode de réalisation, quant à l'issue du parcours de la structure de donnée, aucune instance de fonction n'est identifié, le procédé de l'invention met en oeuvre une étape de compilation à la volée d'une instance de fonction adaptée au contexte d'exécution courant. Cette compilation à la volée peut être mise en oeuvre en combinaison à l'exécution d'une instance par défaut. Par exemple, dans le cas d'une architecture multicoeurs, l'instance par défaut est exécutée sur un coeur, pour permettre à l'application de continuer son exécution pendant qu'une instance particulière est compilée sur un autre coeur pour satisfaire au contexte d'exécution courant. Ainsi, lors de la première apparition du contexte d'application courant, l'instance par défaut est utilisée et une instance utilisable pour le contexte courant est compilée et éventuellement insérée dans une bibliothèque dynamique répertoriant les instances de fonctions. La structure de données répertoriant les instances associées aux contextes d'exécution est alors mise à jour pour insérer l'identifiant de l'instance compilée à la volée. Cette nouvelle instance peut alors être utilisée à nouveau (sans compilation) lorsqu'un prochain contexte d'exécution y fera référence. On décrit, en relation avec la figure 1, le principe général de l'invention. Une fonction �fcod � 10 est écrite dans un langage de programmation (par exemple du C++). Elle contient par exemple un code, en pseudo code informatique, du type : Void fcod(int n, ...) { } Elle permet de réaliser une tâche donnée. Cette fonction 10 est compilée (11) pour produire une instance de fonction 12 (cpu.exe) destinée à être exécutée sur un processeur multicoeurs généraliste. Elle est également compilée (13) pour produire une instance de fonction 14 (gpu.exe) destinée à être exécutée sur un processeur graphique. Ces deux instances de fonction sont ensuite insérée (15) dans un outil de test de performance 16 qui calcul un arbre de décision (17). L'outil de test de performance 16 procède à des exécutions successives des instances en modifiant les paramètres d'entrée de celles-ci et établit un graphe de performance en fonction des contextes d'exécutions des tests. Ces mesures de performances permettent de calculer l'arbre de décision (17), représenté ici sous la forme d'une fonction � fcod_decision � qui permet de prendre la décision de la fonction à utiliser en fonction du contexte d'exécution. La fonction � fcod_decision � est par exemple écrite, en pseudo code informatique, comme ceci : Void fcod_decision(int n, ...) { If (n = 4 utiliser cpu.exe avec 4 cœurs } elseif (gpu type == GT8800) { 14 utiliser gpu.exe } Lors de l'exécution de l'application, l'arbre de décision est chargé (18). Lorsque la fonction �fcod � doit être appelée (19 : appel de � fcod � avec le paramètre 2000), c'est en fait la fonction � fcod_decision � qui est appelée, laquelle renvoie l'instance à utiliser (12, 14) en fonction du contexte d'exécution. Préalablement à l'appel de � fcod_decision �, un test (20) est réalisé pour savoir si cette fonction � fcod_decision � existe. Si ce n'est pas le cas, l'instance par défaut est utilisée. Le test 20 peut s'écrire, en pseudo code informatique, de la façon suivante : If (!exist(fcod_decision)) { fcod(2000,...) ; } else { fcod decision(2000, ...) } Le remplacement de l'appel de la fonction � fcod � par la fonction � fcod_decision � est possible car postérieurement à la création de l'arbre de décision (17), le code d'origine de l'application a été modifié pour remplacer l'appel et une nouvelle phase de compilation de l'application a été réalisée. Par la suite, on présente notamment le cas de la mise ne oeuvre du procédé de l'invention à une architecture multicoeurs. Il est clair cependant que l'invention ne se limite pas à cette application particulière. 5.2 Description d'un mode de réalisation On présente, dans ce mode de réalisation, la mise en oeuvre du procédé de l'invention dans une architecture multicoeurs. L'utilisation des architectures multicoeurs suppose que le code de l'application a préalablement été partitionné en sections séquentielles et en sections parallèles. Un code principal s'exécutant sur un coeur � maître � lance l'exécution de séquences d'instructions sur les autres ressources de calculs. Dans la suite nous dénommons �codelets � ces séquences d'instructions, qui sont des instances de fonctions selon l'invention. Ces instances de fonctions sont exécutées sur un coeur différent du coeur maitre. Une codelet est une fonction particulière qui respecte les contraintes suivantes : les tailles des données passées en paramètre sont connues (c'est par exemple la longueur de la chaine ou du tableau passé en paramètre, qui définissent une taille de problème) ; les paramètres pointeurs et tableaux ne sont pas aliasés (ils ne sont pas passés par référence) ; - elle ne dispose pas d'accès direct à des variables globales (ces variables, si elles sont nécessaires, sont passées en paramètre) ; - la codelet ne produit pas d'entrée/sortie (par d'affichage ou d'attente de retour de la part de l'utilisateur) ; - le calcul de la codelet (le résultat) est identique pour toutes valeurs de paramètres identiques (i.e. y compris les zones pointées par les paramètres tableaux et pointeurs). Ces codelets existent éventuellement en multiples versions exécutables afin de prendre en compte l'hétérogénéité de l'architecture (c'est une première catégorie d'instance). Par ailleurs, ils existent des versions de codelets exécutables spécialement optimisées pour certaines des données d'entrée (c'est une seconde catégorie d'instance) : ces versions exécutables spécialement optimisées pour certaines données d'entrées implémentent toutes les mêmes fonctionnalités, mais peuvent par exemple être écrites différemment en fonction de la taille N du problème d'entrée. Si par exemple une codelet est en charge du tri d'un tableau de taille N, le code source de la codelet pourra être différents selon la taille du tableau : pour un tableau de taille N inférieure à 100, un premier code source servira à la compilation d'une première instance tandis que lorsque la taille N sera supérieure à 100, un deuxième code source sera utilisé pour la compilation d'une deuxième instance. Il y a donc dans ce mode de réalisation plusieurs niveaux d'instances des fonctions. On dénomme contexte d'exécution d'une codelet exécutable un ensemble comprenant au moins certaines des données suivantes : la configuration matérielle d'un noeud de calcul (composants de calculs, de mémorisation, de connexion) ; la taille des données en entrée de la codelet (la taille des paramètres) ; - l'occupation des coeurs de calcul (mémoire et unités de calcul); - les données disponibles dans les mémoires locales coeurs ; - les droits d'utilisation des composants des noeuds. Ainsi, la description d'une codelet mis en oeuvre peut comporter de nombreuses instances exécutables, comme cela a déjà été mentionné, caractérisées par : - des contraintes d'appel de l'instance (paramètres acceptables) ; - architecture cible de l'instance et paramètre de la cible (nombre de coeurs par exemple) ; - profil de performance de l'instance. Les contraintes d'appel de l'instance décrivent les données d'entrée acceptables du point de vue d'une exécution correcte. Par exemple, une instance pourra être mise en oeuvre pour une taille de donnée fixée et être incorrecte dans tous les autres cas. Les contraintes usuelles auxquelles les instances sont soumises sont les suivantes : intervalle de tailles des données ; - absence ou présence nécessaire d'un paramètre ; - intervalle de valeurs de certains paramètres ; - corrélation de valeur entre paramètres. Les architectures cibles de l'instance sont les mutlicoeurs (ou une partie des mutlicoeurs) pouvant l'exécuter correctement si les contraintes d'appel sont respectées. Les architectures cibles sont décrites en deux parties : Qualitative : le type de jeux d'instructions nécessaires ; - Quantitative : le nombre de ressources minimum ou maximum des ressources nécessaires. Ces ressources sont des unités de calculs ou des unités de mémorisation. Le profil de performance de l'instance est typiquement une table (ou tout autre méthode de description appropriée) qui indique le niveau de performance atteint (par exemple en Gigaflops) en fonction de la valeur de certains paramètres d'entrée (typiquement ceux indiquant la complexité du problème) en fonction des ressources d'exécution allouée. Par exemple cette table pourrait avoir le contenu ci-dessous : pour une instance ayant un paramètre N, chaque performance correspond à une seule instance exécutable ou plusieurs qui atteignent le niveau de performance indiqué dans les cellules : c Cible matérielle E Proc XY 3Ghz Proc XY 3Ghz GPU GPU 2 coeurs WWW 4 coeurs ZZZ 1000 1 Gigaflops 0.8 Gigaflops 0.2 Gigaflops 0.4 Gigaflops 10000 5 Gigaflops 9 Gigaflops 30 Gigaflops impossible Dans la suite on décrit, selon l'invention, les deux techniques qui mettent en oeuvre les instances telles que définies précédemment 5.3 Structure de données d'allocations de ressources et d'instances associées L'invention introduit une nouvelle technique de mise en oeuvre des nouvelles instances de fonctions qui ont été définies précédemment. Dans un mode de réalisation particulier de l'invention, les instances de fonctions sont sélectionnées, au moment de l'exécution de l'application, à l'aide d'une structure de données dont la caractéristique est de permettre à l'application de décider de l'instance à exécuter en fonction du contexte d'exécution. Cette structure de données peut par exemple se présenter sous la forme d'un arbre de décision, mais ce n'est pas obligatoire. Il est en revanche hautement souhaitable que la structure utilisée permette une identification rapide de l'instance à utiliser pour qu'un des bénéfices apportés par l'invention, à savoir l'introduction d'une contextualité d'utilisation d'instance de fonction, soit réalisé plus rapidement qu'une compilation à la volée. Ainsi, à la place d'un arbre de décision, des tables de hashage ou des tableaux à n dimensions peuvent être utilisés, dans lesquels n est le nombre de contraintes du contexte d'exécution. Dans ce mode de réalisation, les arbres de décision sont utilisés. Un arbre de décision dans le cadre de l'utilisation des architectures mutlicoeurs hétérogènes ou homogènes permet, selon l'invention, de sélectionner pendant l'exécution d'une application l'instance d'une codelet qui fournira la meilleure performance en prenant en compte le contexte d'exécution, les architectures cibles et les contraintes d'appel. L'arbre de décision est construit suivant le profil de performance et un ensemble de ressources matérielles disponibles. Typiquement l'arbre de décisions (pas nécessairement binaire) se présente sous la forme suivante (décrite en relation avec la figure 2). Les cercles représentent des sélecteurs tandis que les feuilles (carrés) représentent les instances à utiliser. Un sélecteur choisit le fils du noeud à utiliser. Lorsque le fils est une feuille, l'instance correspondante est appelée pour exécuter l'instance de la codelet, dont l'identifiant (la référence) est inscrit dans la feuille. Une instance sera utilisée si l'ensemble des sélecteurs définisse le chemin de la racine à l'instance. Par exemple, sur la base de l'exemple de profil de performance de la section précédente, si l'on suppose que : - V, est la référence de la mise en oeuvre de la codelet sur le Proc XY 3Ghz avec 2 coeurs ; - V2 est la référence de la mise en oeuvre de la codelet sur le Proc XY 3Ghz avec 4 coeurs ; - V3 est la référence de la mise en oeuvre de la codelet sur Proc XY 3Ghz avec 2 coeurs ; - V4 est la référence de la mise en oeuvre de la codelet sur le GPU ZZ. Par ailleurs on suppose que au moins deux coeurs sont toujours disponibles (allocation des ressources au démarrage de l'application). Les sélecteurs pourraient être les suivants : - S, vaut : fils gauche si N est inférieur à 10000 sinon fils droit ; - S2 vaut : fils gauche si GPU ZZ n'est pas disponible sinon fils droit ; - S3 vaut : fils gauche si 4 coeurs sont disponibles sinon fils droit. Avec cet arbre de décision, si le paramètre N (qui représente ici la taille/complexité du problème) est supérieur ou égal à 1000 et que le GPU ZZ est disponible, l'instance V, sera utilisée pour implémenter le codelet (l'identifiant de l'instance est accessible dans les feuilles de l'arbre). Comme on peut le voir sur la base de cet exemple, de nombreuses versions de l'arbre de décisions sont possibles à partir du profil de performance utilisé. 5.3.1 Construction et utilisation des arbres de décisions La construction des arbres de décisions peut être mise en oeuvre manuellement ou automatiquement à partir des profils de performances. Cette partie est conduite, selon l'invention, avant la construction du binaire de l'application qui réunit les différentes instances soit dans le binaire ou dans des bibliothèques (statiques ou dynamiques) de l'application. Cette dernière possibilité étant préférable dans la mesure où elle permet à l'application d'être indépendante des instances qui peuvent-elles mêmes faire l'objet d'optimisations successives et être installées par exemple lors d'opérations de mise à jour de l'application. Un arbre de décision, construit pour chaque codelet, est inséré dans le code de l'application à la place de l'appel de la codelet. A l'exécution, l'arbre de décisions redirige l'exécution sur l'instance la plus appropriée au contexte d'exécution. Le contexte d'exécution est fourni par l'application (valeur des paramètres, par exemple la taille du problème ou un tableau de paramètres d'entrée) et par l'exécutif (et/ou le système d'exploitation) de support à l'exécution de l'application. Par exemple, l'exécutif garde trace de l'occupation des ressources matérielles et autorise ou non l'attribution d'une ressource à une codelet donné. Ce processus est décrit en relation avec la figure 3, pour une codelet donné : En phase de création de l'application (30) : - des mesures de performance sur les diverses cibles matérielles (Cl à Cn) sont effectuées (301) ; - un profil de performance est construit (302) ; à partir du profil de performance l'arbre de décisions est construit (303) ; - l'arbre de décision est intégré dans l'application par insertion des tests correspondant dans le code source (phase de préprocessing - 304) ; - le code résultant est compilé pour produire un code exécutable BIN (avec les instances nécessaires à la mise en oeuvre de la codelet) (305) ; En phase d'exécution de l'application (31) : - le code de l'application BIN est exécuté (316) ; si un appel de codelet est rencontré, l'arbre de décision est interprété ou parcouru (317) ; - l'instance déterminée à l'issue de l'interprétation dans l'arbre de décision est appelée (318) ; - l'instance est exécutée et le contrôle est retourné à l'application (319). Ainsi, l'invention offre une réponse optimale au problème de prise en charge d'architectures multiples en proposant une instance qui est adaptée au contexte d'exécution de l'application. 5.4 Exécutif décisionnel Selon une variante de réalisation, l'invention introduit la notion d'exécutif décisionnel. Il s'agit du gestionnaire des applications capables d'allouer globalement les ressources et de sélectionner les codes adaptés. Un exécutif décisionnel a pour objectif de dissocier l'utilisation des arbres de décisions du code binaire de l'application. Ceci permet d'adapter le processus a postériori après distribution des applications et d'adapter celle-ci à de nouveaux contextes d'exécution qui n'existait pas à la diffusion de l'application. L'exécutif décisionnel peut ainsi être distribué sous la forme de mises à jour logicielles qui sont réalisées de manière automatique. On suppose une application comportant un certain nombre de codelets [C,,...,C,,]. La détection des applications par l'exécutif peut par exemple être effectuée par un hash-code robuste sur le code binaire de l'application et/ou au moment de sa compilation l'application intègre une fonction capable d'indiquer son identité sans ambigüité. Cette fonction pourra être activée par l'exécutif décisionnel. Le processus est globalement le suivant : 1. lancement de l'application ; 2. l'application charge et lance l'exécutif décisionnel ; 3. l'exécutif décisionnel identifie l'application ; 4. l'exécutif décisionnel identifie la configuration du noeud d'exécution ; 5. l'exécutif décisionnel détermine les codelets en présence dans l'application ; 6. l'exécutif décisionnel détermine les arbres de décisions embarqués ; 7. lors d'un appel de codelet, l'application transfert le contrôle dans l'exécutif décisionnel qui utilise les arbres de décisions embarqués pour choisir la variante de la codelet à utiliser ; 8. l'exécutif décisionnel retourne le contrôle à l'application. La manière d'embarquer les arbres de décisions dans l'exécutif décisionnel est variée. Par exemple : - dans un fichier de configuration chargé par l'exécutif ; - par accès à une base de données locale ou distante ; - par intégration des arbres dans le code de l'exécutif ; - par chargement d'une bibliothèque dynamique qui intègre les arbres. L'exécutif décisionnel est don particulièrement bien adapté à des applications qui peuvent nécessiter de nombreuses mises à jour logicielles, soit parce que l'application est par exemple en phase de test et qu'il est nécessaire d'améliorer ses performances en permanence et donc de réaliser des mise à jour de l'arbre de décision de manière régulière, soit encore parce que l'application est modulaire et qu'un utilisateur peut avoir l'envie ou le besoin de charger de nouveaux modules et dans ce cas d'utiliser un exécutif décisionnel différent en fonction des modules de l'application qui sont installés. REVENDICATIONS1. Procédé de réalisation d'un appel d'une instance d'une fonction présente au sein d'au moins un premier module logiciel et requise par un second module logiciel, dit module logiciel appelant, caractérisé en ce qu'il comprend : - une étape d'obtention d'un contexte d'exécution courant, ledit contexte d'exécution courant dépend d'au moins une situation d'exécution dudit module logiciel appelant et comprend des données d'exécution ; - une étape de sélection de ladite instance de fonction, parmi au moins deux instances disponibles, en fonction desdites données d'exécution dudit contexte d'exécution courant. 2. Procédé de réalisation d'un appel selon la revendication 1, caractérisé en ce que ladite étape de sélection de ladite instance de fonction comprend : une étape de chargement, au sein d'un environnement d'exécution dudit module logiciel appelant, d'une structure de données préalablement construite associée à Iadite fonction et à une pluralité de contexte d'exécution ; - une étape de recherche, au sien de ladite structure de données, d'une référence à ladite instance de fonction à sélectionner en fonction desdites données d'exécution dudit contexte d'exécution courant, délivrant un identifiant d'instance ; - une étape d'identification, parmi lesdites au moins deux instances dudit premier module logiciel, de ladite instance de fonction à sélectionner à l'aide dudit identifiant d'instance. 3. Procédé selon la revendication 2, caractérisé en ce que ladite étape de sélection comprend en outre, lorsque ladite de recherche est infructueuse, une étape de sélection d'une instance d'appel par défaut. w 2938091 3 4. Procédé selon l'une quelconque des revendications 1 à 3, caractérisé en ce que ledit contexte d'exécution courant comprend en outre des données relatives à : une architecture matérielle d'une plateforme matérielle sur laquelle ledit 5 module logiciel appelant s'exécute ; - une charge de travail courante de ladite plateforme matérielle sur laquelle ledit module logiciel appelant s'exécute. 5. Procédé selon la revendication 4, caractérisé en ce que ledit contexte 10 d'exécution courant est matérialisé sous la forme de données d'exécution dépendantes dudit module logiciel appelant et de ladite plateforme matérielle sur laquelle ledit module logiciel appelant s'exécute. 6. Procédé selon l'une quelconque des revendications 1 à 5, caractérisé en ce 15 que ladite d'au moins une situation d'exécution dudit module logiciel appelant comprend une taille de problème (n), ladite taille de problème (n) étant un paramètre de ladite instance de fonction sélectionnée. 7. Procédé selon l'une quelconque des revendications 5 et 6, caractérisé en ce 20 que ladite structure de données se présente sous la forme d'un arbre de décision, dans lequel chaque noeud dudit arbre de décision correspond à une décision à prendre en fonction d'au moins une desdites données d'exécution dudit contexte d'exécution courant. 25 8. Procédé selon la revendication 7, caractérisé en ce qu'au moins certaines feuilles dudit arbre de décision comprennent au moins un identifiant d'instance de fonction à appeler. 9. Procédé selon la revendication 8, caractérisé en ce que lorsqu'une feuille 30 dudit arbre de décision ne comprend pas d'identifiant d'instance defonction à appeler, ledit procédé comprend une étape de sélection d'une instance de fonction utilisée par défaut. 10. Procédé selon la revendication 8, caractérisé en ce que lorsqu'une feuille dudit arbre de décision ne comprend pas d'identifiant d'instance de fonction à appeler, ledit procédé comprend une étape de compilation dynamique d'une instance de fonction à utiliser en fonction d'au moins certaines données dudit contexte d'exécution courant. 11. Procédé de construction d'une structure de données de sélection d'une instance de fonction à appeler lorsqu'un premier module logiciel, dit module logiciel appelant, requiert I'exécution d'une fonction auprès d'un second module logiciel selon le procédé de la revendication 1, ledit procédé de construction comprend, pour une fonction donnée : - une étape de compilation d'une pluralité d'instances de fonction, chaque instance étant configurée pour présenter une performance probable en fonction d'au moins un contexte d'exécution déterminé ; une étape d'analyse de la performance réelle desdites instances de ladite pluralité d'instance de fonctions délivrant des indices de performances ; - une étape de construction de ladite structure de données associant un identifiant d'instance de fonction à un ensemble de données d'un contexte d'exécution de sorte que ladite structure de décision permettent de décider de l'instance de fonction à appeler en fonction desdits indices de performances délivrés. 12. Dispositif de réalisation d'un appel d'une instance d'une fonction présente au sein d'au moins un premier module logiciel et requise par un second module logiciel, dit module logiciel appelant, caractérisé en ce qu'iI comprend : - des moyens d'obtention d'un contexte d'exécution courant, ledit contexted'exécution courant dépend d'au moins une situation d'exécution dudit module logiciel appelant et comprend des données d'exécution ; - des moyens de sélection de ladite instance de fonction, parmi au moins deux instances disponibles, en fonction desdites données d'exécution dudit contexte d'exécution courant. 13. Programme d'ordinateur caractérisé en ce qu'il comprend des instructions de code de programme pour la mise en oeuvre du procédé de réalisation d'un appel selon la revendication 1, lorsque ce programme est exécuté par un processeur. 14. Programme d'ordinateur caractérisé en ce qu'il comprend des instructions de code de programme pour la mise en oeuvre du procédé de construction selon la revendication 11, lorsque ce programme est exécuté par un processeur mettant en oeuvre un programme d'ordinateur selon la revendication 13.