Login| Sign Up| Help| Contact|

Patent Searching and Data


Title:
METHOD AND DEVICE FOR LOADING AND EXECUTING INSTRUCTIONS WITH DETERMINISTIC CYCLES IN A MULTICORE AVIONICS SYSTEM HAVING A BUS, THE ACCESS TIME OF WHICH IS UNPREDICTABLE
Document Type and Number:
WIPO Patent Application WO/2010/139896
Kind Code:
A1
Abstract:
The invention particularly relates to a method and device for loading and executing a plurality of instructions in an avionics system including a processor having at least two cores and a memory controller, each of the cores including a private memory. The plurality of instructions is loaded and executed by execution slots such that, during a first execution slot, a first core has access to the memory controller for transmitting (215) at least one piece of data stored in the private memory thereof and for receiving (220) and storing at least one datum and an instruction from the plurality of instructions in the private memory thereof, while the second core does not have access to the memory controller and executes (210) at least one instruction previously stored in the the private memory thereof and such that, during a second execution slot, the roles of the two cores are reversed.

Inventors:
JEGU VICTOR (FR)
TRIQUET BENOIT (FR)
ASPRO FREDERIC (FR)
Application Number:
PCT/FR2010/051071
Publication Date:
December 09, 2010
Filing Date:
June 02, 2010
Export Citation:
Click for automatic bibliography generation   Help
Assignee:
AIRBUS OPERATIONS SAS (FR)
JEGU VICTOR (FR)
TRIQUET BENOIT (FR)
ASPRO FREDERIC (FR)
International Classes:
G06F15/167; G06F9/38; G06F13/16
Foreign References:
EP2015174A12009-01-14
US20030091040A12003-05-15
Other References:
JAKOB ROSEN ET AL: "Bus Access Optimization for Predictable Implementation of Real-Time Applications on Multiprocessor Systems-on-Chip", REAL-TIME SYSTEMS SYMPOSIUM, 2007. RTSS 2007. 28TH IEEE INTERNATIONAL, IEEE, PISCATAWAY, NJ, USA, 1 December 2007 (2007-12-01), pages 49 - 60, XP031194167, ISBN: 978-0-7695-3062-8
JONGSUN KIM ET AL: "A Cost-Effective Latency-Aware Memory Bus for Symmetric Multiprocessor Systems", IEEE TRANSACTIONS ON COMPUTERS, IEEE SERVICE CENTER, LOS ALAMITOS, CA, US, vol. PP, no. 12, 1 December 2008 (2008-12-01), pages 1714 - 1719, XP011247299, ISSN: 0018-9340
HONGZHONG ZHENG ET AL: "Memory Access Scheduling Schemes for Systems with Multi-Core Processors", PARALLEL PROCESSING, 2008. ICPP '08. 37TH INTERNATIONAL CONFERENCE ON, IEEE, PISCATAWAY, NJ, USA, 9 September 2008 (2008-09-09), pages 406 - 413, XP031321576, ISBN: 978-0-7695-3374-2
Attorney, Agent or Firm:
IMBERT DE TREMIOLLES, GHISLAIN (FR)
Download PDF:
Claims:
REVENDICATIONS

1. Procédé de chargement et d'exécution à cycles d'exécution déterministes d'une pluralité d'instructions dans un système avionique comprenant au moins un processeur ayant au moins deux cœurs (305, 305') et au moins un contrôleur de mémoire (355), chacun desdits au moins deux cœurs disposant d'une mémoire privée (310, 340, 345, 350), ce procédé étant caractérisé en ce que ladite pluralité d'instructions est chargée et exécutée par tranches d'exécution et en ce qu'il comprend les étapes suivantes, - durant une première tranche d'exécution, o autorisation d'accès audit au moins un contrôleur de mémoire à un premier desdits au moins deux cœurs, ledit premier cœur transmettant (215) audit au moins un contrôleur de mémoire au moins une donnée mémorisée dans sa mémoire privée, préalablement modifiée, et recevant (220) au moins une donnée et au moins une instruction de ladite pluralité d'instructions, ladite au moins une donnée et ladite au moins une instruction reçues étant mémorisées dans sa mémoire privée ; o interdiction d'accès audit au moins un contrôleur de mémoire à un second desdits au moins deux cœurs, ledit second cœur exécutant (210) au moins une instruction préalablement mémorisée dans sa mémoire privée ; - durant une seconde tranche d'exécution, o interdiction d'accès audit au moins un contrôleur de mémoire audit premier cœur, ledit premier cœur exécutant (235) au moins une instruction préalablement mémorisée dans sa mémoire privée ; et, o autorisation d'accès audit au moins un contrôleur de mémoire audit second cœur, ledit second cœur transmettant (225) audit au moins un contrôleur de mémoire au moins une donnée mémorisée dans sa mémoire privée, préalablement modifiée, et recevant (230) au moins une donnée et au moins une instruction de ladite pluralité d'instructions, ladite au moins une donnée et ladite au moins une instruction reçues étant mémorisées dans sa mémoire privée. 2. Procédé selon la revendication 1 selon lequel ledit au moins un processeur comprend en outre au moins un second contrôleur de mémoire, le procédé comprenant en outre les étapes suivantes,

- durant une première phase de ladite première tranche d'exécution, autorisation d'accès à un premier desdits au moins deux contrôleurs de mémoire audit premier cœur et interdiction d'accès à un second desdits au moins deux contrôleurs de mémoire audit premier cœur ;

- durant une seconde phase de ladite première tranche d'exécution, autorisation d'accès audit second contrôleur de mémoire audit premier cœur et interdiction d'accès audit premier contrôleur de mémoire audit premier cœur ; - durant une première phase de ladite seconde tranche d'exécution, autorisation d'accès audit premier contrôleur de mémoire audit second cœur et interdiction d'accès audit second contrôleur de mémoire audit second cœur ; et,

- durant une seconde phase de ladite seconde tranche d'exécution, autorisation d'accès audit second contrôleur de mémoire audit second cœur et interdiction d'accès audit premier contrôleur de mémoire audit second cœur.

3. Procédé selon la revendication 1 ou la revendication 2 selon lequel au moins un desdits au moins deux cœurs est dédié à des opérations de transmission et de réception de données vers et depuis une interface de communication réseau. 4. Procédé de traitement d'une pluralité d'instructions pour permettre le chargement et l'exécution à cycles d'exécution déterministes de ladite pluralité d'instructions selon l'une quelconque des revendications précédentes, le procédé de traitement comprenant une étape de découpage de ladite pluralité d'instructions en tranches d'exécution, chaque tranche d'exécution comprenant une séquence de transfert et une séquence d'exécution, ladite séquence de transfert permettant la transmission d'au moins une donnée préalablement mémorisée et la réception et la mémorisation d'au moins une donnée et d'au moins une instruction, ladite au moins une donnée reçue étant nécessaire à l'exécution de ladite au moins une instruction reçue et permettant l'exécution de ladite au moins une instruction reçue, de façon autonome, durant l'exécution de ladite séquence d'exécution. 5. Procédé selon la revendication précédente selon lequel ladite étape de découpage est basée sur la résolution d'un système d'équations linéaires représentant des contraintes d'exécution des instructions de ladite pluralité d'instructions selon au moins une caractéristique d'un processeur adapté à exécuter lesdites tranches d'exécution. 6. Procédé selon la revendication 4 ou la revendication 5 selon lequel la durée desdites tranches d'exécution est constante et prédéterminée.

7. Procédé selon la revendication précédente selon lequel ladite durée est déterminée par le temps de transmission de données préalablement modifiées et le temps de réception de données et d'instructions à exécuter. 8. Programme d'ordinateur comprenant des instructions adaptées à la mise en œuvre de chacune des étapes du procédé selon l'une quelconque des revendications précédentes lorsque ledit programme est exécuté un processeur.

9. Dispositif comprenant des moyens adaptés à la mise en œuvre de chacune des étapes du procédé selon l'une quelconque des revendications

1 à 7.

10. Aéronef comprenant le dispositif selon la revendication précédente.

Description:
« Procédé et dispositif de chargement et d'exécution d'instructions à cycles déterministes dans un système avionique multi-cœurs ayant un bus dont le temps d'accès est non prédictible »

La présente invention concerne l'architecture de systèmes de type avionique et plus particulièrement un procédé et un dispositif de chargement et d'exécution d'instructions à cycles déterministes dans un système avionique multi-cœurs ayant un bus dont le temps d'accès est non prédictible.

Les aéronefs modernes comprennent de plus en plus de systèmes électroniques et informatiques pour améliorer leurs performances et assister le pilote ainsi que les membres d'équipage lors de leurs missions. Ainsi, par exemple, les commandes de vol électriques permettent de réduire la complexité mécanique de la transmission des commandes aux actuateurs et donc la masse associée à ces commandes. De même, la présentation d'informations pertinentes permet au pilote d'optimiser les trajectoires de vol et de répondre rapidement à tout incident détecté. De telles informations sont notamment la vitesse, la position, le cap, des données de météorologie et de navigation. L'ensemble de ces systèmes électroniques et informatiques est généralement appelé l'avionique. Pour des raisons notamment de fiabilité, de simplicité et de certification, l'avionique a souvent été répartie de façon fonctionnelle par modules spécifiques, aussi appelé LRU (sigle de Une Replaceable Unit en terminologie anglo-saxonne). Ainsi, par exemple, les commandes de vol sont gérées dans un dispositif particulier tandis que l'alimentation électrique est gérée dans un autre. Une fonction spécifique est ainsi associée à chaque module.

Par ailleurs, chaque module supportant une fonction critique est, de préférence, redondant de telle sorte que la défaillance d'un module n'entraîne pas la perte de la fonction associée. L'exploitation d'un aéronef utilisant un module redondant lorsque le module principal est défaillant nécessite une opération de maintenance. Afin d'améliorer les fonctionnalités des aéronefs, réduire le poids des équipements électroniques et faciliter les opérations de maintenance, l'avionique est maintenant de plus en plus intégrée selon une architecture appelée IMA (sigle d'Integrated Modular Avionics en terminologie anglo- saxonne). Selon cette architecture, les fonctionnalités sont décorrélées des systèmes, c'est-à-dire des calculateurs ou des ressources de calcul, dans lesquels elles sont implémentées. Néanmoins, un système de ségrégation permet d'isoler chacune des fonctionnalités de telle sorte que la défaillance d'une fonction n'ait pas d'influence sur une autre. De tels systèmes mettent en œuvre différents modules, en particulier des modules de traitement de données, appelés CPM (sigle de Core Processing Module en terminologie anglo-saxonne), des modules de commutation de données, appelés ASM (sigle d'Avionic Switch Module en terminologie anglo-saxonne), et des modules d'alimentation électrique, aussi appelés PSM (sigle de Power Supply Module en terminologie anglo-saxonne).

Les modules de traitements de données comprennent des modules dits « hautes performances » pour les applications générales d'avionique, des modules dits « temps critique » pour les applications d'avionique ayant de forte contraintes de déterminisme temporel et des modules de type serveur pour les applications du monde ouvert, non critiques.

Un module de traitement de données est généralement composé d'un ou de plusieurs processeurs, aussi appelés CPU (sigle de Central Processing Unit en terminologie anglo-saxonne), associés à un ou plusieurs bancs mémoire de type RAM (sigle de Random Access Memory en terminologie anglo-saxonne) et FLASH.

Les communications entre plusieurs CPU d'un CPM sont, de préférence, assurées à l'aide de liens directs vers une mémoire partagée ou à travers une mémoire d'échange d'une interface de communication, par exemple une interface AFDX (sigle d'Avionic FuII DupleX en terminologie anglo- saxonne).

Afin de permettre le calcul du WCET (sigle de Worst Case Execution Time en terminologie anglo-saxonne) les modules de traitement de données dits temps critique doivent utiliser des processeurs et des architectures de mémoire permettant leur déterminisme temporel.

Pour réaliser un module de traitement de données dit temps critique, appelés CPM TC (sigle de Core Processing Module Time Critical en terminologie anglo-saxonne) dans la suite de la description, un nombre important de processeurs relativement simples peut être utilisé, avec une exécution du code en mémoire RAM statique ou en mémoire de type flash afin de garantir le déterminisme temporel.

La figure 1 illustre schématiquement un CPM mettant en œuvre une telle architecture. Comme illustré, le CPM 100 comprend ici quatre processeurs « simple cœur » 105-1 à 105-4 et, associées à chaque processeur, des mémoires de type DDRAM (sigle de Double Data rate Random Access Memory en terminologie anglo-saxonne), génériquement référencées 110, et de type flash, génériquement référencées 115. Par ailleurs, le CPM comprend un ensemble 120 de circuits logiques permettant notamment aux processeurs 105- 1 à 105-4 d'échanger des données avec d'autres composants de l'aéronef via un module d'entrée/sortie 125.

Cependant, l'utilisation d'un nombre important de processeurs augmente le risque de panne, ou MTBF (sigle de Mean Time Between Failures en terminologie anglo-saxonne), ainsi que le poids et les coûts de développement.

Par ailleurs, en dépit de la puissance de calcul requise dans les CPM TC, des processeurs performants, super scalaires, qui exécutent des instructions de code depuis un banc de mémoire RAM dynamique ne sont pas ou mal utilisés à cause du temps de rafraîchissement de la mémoire, des changements de lignes, colonnes et/ou banques et surtout de la latence plus importante du contrôleur de mémoire. En d'autres termes, les CPM TC ne mettent généralement pas efficacement en œuvre des processeurs basés sur des architectures multi-cœurs utilisant des mémoires caches. En effet, les CPM TC ont besoin d'un déterminisme fort de leur temps d'exécution et leurs mémoires caches créent une variabilité difficilement déterminable due à un effet d'historique selon lequel, en fonction des événements passés, une information peut encore être ou non présente en mémoire cache. Il peut alors être nécessaire de la recharger sans que cela soit déterminé à l'avance. Il en va de même pour les séquences d'instructions de type pipeline des cœurs des processeurs et des contrôleurs de mémoire pour lesquelles les instructions peuvent être réparties sur plusieurs cycles créant ainsi des dépendances historiques.

Par conséquent, pour être déterministes, les CPM TC doivent écarter les mécanismes à l'origine de ces variabilités et utiliser des marges permettant de déterminer à l'avance les temps d'exécution rendant ainsi l'utilisation de processeurs multi-cœurs inefficace.

L'invention permet de résoudre au moins un des problèmes exposés précédemment. Plus particulièrement, il est possible, selon l'invention, de déterminer à l'avance l'utilisation des mémoires caches de systèmes multi- cœurs de telle sorte que la latence des mémoires ne soit plus un facteur limitant les performances. L'invention permet également, dans une architecture multi- cœurs, multi-processeurs, ou plus généralement à bus processeur partagé, d'obtenir l'indépendance des cœurs de calcul et la détermination de WCET non pessimistes. De plus, l'indépendance vis-à-vis de la latence des mémoires caches autorise la détermination de WCET même si les modèles de mémoire et de contrôleur de mémoire sont imprécis.

L'invention a ainsi pour objet un procédé de chargement et d'exécution à cycles d'exécution déterministes d'une pluralité d'instructions dans un système avionique comprenant au moins un processeur ayant au moins deux cœurs et au moins un contrôleur de mémoire, chacun desdits au moins deux cœurs disposant d'une mémoire privée, ladite pluralité d'instructions étant chargée et exécutée par tranches d'exécution, le procédé comprenant les étapes suivantes,

- durant une première tranche d'exécution, o autorisation d'accès audit au moins un contrôleur de mémoire à un premier desdits au moins deux cœurs, ledit premier cœur transmettant audit au moins un contrôleur de mémoire au moins une donnée mémorisée dans sa mémoire privée, préalablement modifiée, et recevant au moins une donnée et au moins une instruction de ladite pluralité d'instructions, ladite au moins une donnée et ladite au moins une instruction reçues étant mémorisées dans sa mémoire privée ; o interdiction d'accès audit au moins un contrôleur de mémoire à un second desdits au moins deux cœurs, ledit second cœur exécutant au moins une instruction préalablement mémorisée dans sa mémoire privée ; - durant une seconde tranche d'exécution, o interdiction d'accès audit au moins un contrôleur de mémoire audit premier cœur, ledit premier cœur exécutant au moins une instruction préalablement mémorisée dans sa mémoire privée ; et, o autorisation d'accès audit au moins un contrôleur de mémoire audit second cœur, ledit second cœur transmettant audit au moins un contrôleur de mémoire au moins une donnée mémorisée dans sa mémoire privée, préalablement modifiée, et recevant au moins une donnée et au moins une instruction de ladite pluralité d'instructions, ladite au moins une donnée et ladite au moins une instruction reçues étant mémorisées dans sa mémoire privée. Le procédé selon l'invention permet ainsi de mettre en œuvre des technologies basées sur des processeurs multi-cœurs ayant des bus dont le temps d'accès est non prédictible pour des applications ayant de forte contraintes de déterminisme temporel. En particulier, le procédé permet l'utilisation de mémoires de type DDRx fonctionnant en rafale (mode appelé burst en terminologie anglo-saxonne), de cœurs travaillant à des fréquences supérieures à 1 GHz, la mise en œuvre d'architecture massivement parallèle et l'intégration électronique sous forme de composants uniques.

Bien que le découpage de l'activité des cœurs en longues phases d'exécution, sans accès à une mémoire partagée et en longues phases d'accès à une mémoire partagée, sans calcul, semble inefficace à première vue, il l'est du fait des applications avioniques envisagées et du découpage des applications. Le temps des phases d'accès mémoire est avantageusement inférieur au temps total passé par un cœur à attendre la complétion de chacun de ces accès pour que le modèle d'exécution soit efficace.

Un autre avantage significatif est la simplification et la forte réduction de pessimisme des calculs de WCET par analyse statique du fait de la présence en mémoire privée des données utilisées dans les phases de calcul.

Un autre avantage concerne les outils d'analyse statique basés sur un modèle du processeur. L'outil n'ayant pas à considérer dans ses analyses les scénarii incluant les accès à la mémoire partagée, le modèle du processeur peut être réduit au seul cœur et à ses mémoires privées.

Cette approche est également compatible et adaptée aux évolutions des technologies de mémoire qui évoluent vers des débits très élevés, sans réduire les latences en proportion, le but étant ici d'alimenter des mémoires privées de plus en plus importantes et nombreuses. Selon un mode de réalisation particulier, ledit au moins un processeur comprend en outre au moins un second contrôleur de mémoire, le procédé comprenant en outre les étapes suivantes,

- durant une première phase de ladite première tranche d'exécution, autorisation d'accès à un premier desdits au moins deux contrôleurs de mémoire audit premier cœur et interdiction d'accès à un second desdits au moins deux contrôleurs de mémoire audit premier cœur ;

- durant une seconde phase de ladite première tranche d'exécution, autorisation d'accès audit second contrôleur de mémoire audit premier cœur et interdiction d'accès audit premier contrôleur de mémoire audit premier cœur ; - durant une première phase de ladite seconde tranche d'exécution, autorisation d'accès audit premier contrôleur de mémoire audit second cœur et interdiction d'accès audit second contrôleur de mémoire audit second cœur ; et,

- durant une seconde phase de ladite seconde tranche d'exécution, autorisation d'accès audit second contrôleur de mémoire audit second cœur et interdiction d'accès audit premier contrôleur de mémoire audit second cœur.

Le procédé permet ainsi aux cœurs d'accéder à des mémoires partagées pour exécuter des instructions utilisant des données communes. Selon un mode de réalisation particulier, au moins un desdits au moins deux cœurs est dédié à des opérations de transmission et de réception de données vers et depuis une interface de communication réseau pour simplifier la modélisation du processeur. L'invention a également pour objet un procédé de traitement d'une pluralité d'instructions pour permettre le chargement et l'exécution à cycles d'exécution déterministes de ladite pluralité d'instructions selon le procédé décrit précédemment, le procédé de traitement comprenant une étape de découpage de ladite pluralité d'instructions en tranches d'exécution, chaque tranche d'exécution comprenant une séquence de transfert et une séquence d'exécution, ladite séquence de transfert permettant la transmission d'au moins une donnée préalablement mémorisée et la réception et la mémorisation d'au moins une donnée et d'au moins une instruction, ladite au moins une donnée reçue étant nécessaire à l'exécution de ladite au moins une instruction reçue et permettant l'exécution de ladite au moins une instruction reçue, de façon autonome, durant l'exécution de ladite séquence d'exécution.

Le procédé de traitement permet ainsi de découper les instructions en tranches d'exécution pour optimiser le procédé de chargement et d'exécution décrit dont l'efficacité dépend de la capacité à déterminer précisément les informations nécessaires d'une prochaine phase d'exécution pour éviter de sous-estimer ou surestimer la quantité d'informations nécessaires ce qui a pour effet de requérir un accès à la mémoire partagée pour l'exécution des instructions ou d'engendrer une phase de chargement plus longue au temps que passerait le cœur à charger chaque donnée. Selon un mode de réalisation particulier, ladite étape de découpage est basée sur la résolution d'un système d'équations linéaires représentant des contraintes d'exécution des instructions de ladite pluralité d'instructions selon au moins une caractéristique dudit au moins un processeur.

Le procédé selon l'invention permet ainsi d'optimiser l'organisation des tranches d'exécution et de simplifier leur détermination.

La durée desdites tranches d'exécution est, de préférence, constante et prédéterminée. Cette durée est, par exemple, déterminée par le temps de transmission de données préalablement modifiées et le temps de réception de données et d'instructions à exécuter.

L'invention a également pour objet un programme d'ordinateur comprenant des instructions adaptées à la mise en œuvre de chacune des étapes du procédé décrit précédemment lorsque ledit programme est exécuté dans un processeur, un dispositif comprenant des moyens adaptés à la mise en œuvre de chacune des étapes du procédé décrit précédemment ainsi qu'un aéronef comprenant le dispositif selon la revendication précédente. Les avantages procurés par un tel programme d'ordinateur et un tel dispositif sont similaires à ceux évoqués précédemment.

D'autres avantages, buts et caractéristiques de la présente invention ressortent de la description détaillée qui suit, faite à titre d'exemple non limitatif, au regard des dessins annexés dans lesquels :

- la figure 1 représente schématiquement un module de traitement de données comprenant plusieurs processeurs simple cœur ;

- la figure 2, comprenant les figures 2a à 2d, illustre schématiquement un diagramme de temps illustrant les activités d'un processeur comprenant huit cœurs, mis en œuvre conformément à l'invention ;

- la figure 3, comprenant les figures 3a et 3b, illustre un exemple d'architecture multi-cœurs adaptée à mettre en œuvre l'invention ;

- la figure 4, comprenant les figures 4a à 4d, illustre un exemple de mécanisme d'accès, par chaque cœur en phase de transfert d'un processeur multi-cœurs, aux contrôleurs de mémoire de ce processeur ; et,

- la figure 5 illustre schématiquement un module d'un système avionique, dont l'architecture est fondée sur un processeur multi-cœurs tel que celui présenté sur la figure 3b, adapté à mettre en œuvre l'invention.

Les processeurs multi-cœurs de dernière génération, aussi appelés SoC multicores (sigle de System on Chip en terminologie anglo-saxonne), offrent un fort potentiel de puissance de calcul. Cependant, dans le contexte des applications temps réel critique, ce potentiel est difficilement exploitable, notamment pour des raisons de déterminisme et de preuve ou test relatif à des exigences temporelles. II est rappelé ici que la notion de temps réel implique une maîtrise précise du comportement temporel d'applications exécutées, notamment de leur WCET. Le qualificatif « critique » exige, dans le domaine de l'aéronautique, d'apporter une preuve forte de cette maîtrise. Cette problématique de déterminisme provient en partie de l'exécution d'une ou plusieurs applications en concurrence sur chacun des cœurs qui partagent certaines ressources en nombre insuffisant pour ségréguer physiquement tous les chemins de tous les cœurs, en particulier des bus d'échange de données et des mémoires utilisées. Si ces partages ne sont pas maîtrisés (idéalement des accès maîtrisés sont des accès temporellement exclusifs), ils introduisent des contentions généralement indénombrables. Alternativement, la majoration par une analyse de type pire éventualité, worst- case en terminologie anglo-saxonne, est trop pessimiste et conduit à une sous exploitation extrême du processeur multi-cœurs. Une autre source d'indéterminisme provient de la complexité intrinsèque des SoC dont l'ensemble des composants crée des phénomènes d'historiques rendant prohibitif, en termes de coût de calcul, une analyse de type pire éventualité raisonnablement peu pessimiste. Le manque d'observabilité intra-SoC et l'absence de documentation concernant leur architecture rendent également impossible la création de modèles temporels et fiables adaptés aux analyses WCET.

Le système selon l'invention permet de contourner ces difficultés. Il est tout d'abord rappelé qu'à l'intérieur des SoC, chaque cœur dispose d'une ou plusieurs mémoires caches privées. Typiquement, les cœurs envisagés dans les CPM possèdent trois mémoires caches privées par cœurs : une mémoire cache L1_l (ou L1 I) pour les instructions, une mémoire cache L1_D (ou L1 D) pour les données et une mémoire cache L2 unifiée pour les instructions et les données. S'il est important ici que chaque cœur dispose d'une mémoire cache individuelle et d'instructions pour les charger et les décharger, le nombre de niveaux des mémoires caches importe peu.

Alternativement, chaque cœur peut accéder à une mémoire locale ayant une adresse sur le réseau cœur (core-network). De façon similaire, l'invention peut être mise en œuvre avec un dispositif interne du SoC, externe aux cœurs, de type DMA SoC (DMA est le sigle de Direct Memory Access en terminologie anglo-saxonne), piloté par les cœurs ou activé à date fixe sur la base d'un calendrier de tâches, ce dispositif se chargeant de transférer les données dans les deux sens entre les mémoires associées aux cœurs, de type RAM, et les mémoires centrales de type DDR.

Tant qu'une application s'exécute uniquement dans ces mémoires caches, il n'y a aucun problème de conflit de ressources dû à l'architecture multi-cœurs. Les problèmes de complexité des SoC sont aussi, dans ce cas, fortement réduits car les modèles nécessaires à la détermination des WCET se limitent aux cœurs et à leurs mémoires caches. Cependant, les mémoires caches n'ont généralement pas une taille suffisante pour mémoriser les applications dans leur intégralité. De plus, les applications exécutées ont besoin, par nature, de recevoir et de transmettre des données à travers des interfaces d'entrée/sortie, appelées I/O (sigle d'Input/Output en terminologie anglo-saxonne).

Le principe du système selon l'invention est de créer des phases durant lesquelles les applications s'exécutent exclusivement à l'intérieur de leurs mémoires caches privées, aucune sollicitation externe (accès données ou surveillance) ne venant les affecter.

Ce principe apporte les bénéfices suivants :

- l'exécution des phases est entièrement indépendante de l'activité des autres cœurs et l'analyse WCET de ces phases peut suivre une démarche traditionnelle mono-cœur ; et, - la détermination des WCET ne nécessite pas d'autre modèle que celui des cœurs et de leurs mémoires caches privées. En particulier, un modèle des bus de données inter-cœurs et du contrôleur de mémoire n'est pas requis.

Il convient cependant de noter que, comme invoqué précédemment, les applications ne peuvent généralement pas être entièrement contenues dans les mémoires caches privées des cœurs. Par ailleurs, un cœur n'est en général pas dédicacé à une application particulière. De plus, ses données ne sont pas locales, une application devant nécessairement consommer et produire des données utilisées par d'autres applications. Par conséquent, il est nécessaire de gérer les accès à une mémoire partagée et/ou des accès à un ou plusieurs réseaux pour charger et décharger des instructions de code et les données applicatives. Cependant, ces accès doivent être planifiés afin qu'ils soient exclusifs (idéalement) entre les cœurs ainsi que dénombrables et distribués de façon à ce que les conditions les pires soient le moins majorant possible en termes de temps de traitement.

Une solution pour planifier ces accès consiste notamment à définir des points de rendez-vous entre lesquels un cœur dispose d'un accès a chaque ressource (par exemple un contrôleur de mémoire particulier), exclusif et partagé avec un minimum d'autres cœurs. En dehors de ces plages, le cœur ne peut pas accéder à ces ressources. Il est ainsi nécessaire de distribuer les points de rendez-vous de façon à ce que chaque cœur dispose d'un accès équitable aux ressources. De façon avantageuse, ces points de rendez-vous sont placés de façon statique et régulière.

Ainsi, par exemple, pour un processeur disposant de huit cœurs et de deux contrôleurs de mémoire, pour des durées d'exécution et d'accès mémoire équivalentes, quatre cœurs sont autorisés, à tout moment, à accéder à une mémoire via les deux contrôleurs de mémoire, cet accès étant interdit aux quatre autres cœurs. Avantageusement, parmi les quatre cœurs pouvant accéder aux contrôleurs de mémoire, à tout instant, deux et seulement deux accèdent à chaque contrôleur de mémoire. Une durée d'accès mémoire plus courte permet de dédier plus de temps à la phase d'exécution, sans accès mémoire, sans changer la durée totale du cycle mémoire et de l'exécution. Une durée d'accès mémoire plus courte permet de limiter le nombre de cœurs accédant à la mémoire à tout instant.

La figure 2, comprenant les figures 2a et 2b, illustre schématiquement un diagramme de temps illustrant les activités d'un processeur comprenant huit cœurs, mis en œuvre conformément à l'invention. Le type d'activité de chacun des cœurs est ici représenté selon l'axe des temps 200. La figure 2b reprend une partie de la figure 2a pour illustrer plus précisément les rôles d'un cœur particulier, ici le second. Les repères 205-i, 205-j et 205-k définissent des instants qui représentent des points de rendez-vous statiques et réguliers où les cœurs changent leur rôle. Ainsi, par exemple, à l'instant 205-i, le premier cœur exécute une série d'instructions préalablement mémorisées dans sa mémoire cache avec les données correspondantes (référence 210). A partir du même instant, le second cœur échange des données avec un contrôleur de mémoire. Dans un premier temps, il transmet des données mémorisées dans sa mémoire cache vers le contrôleur de mémoire (référence 215). Puis, dans un second temps, il reçoit des données et des instructions du contrôleur de mémoire qu'il mémorise dans sa mémoire cache (référence 220). Ainsi, le second cœur se prépare à une phase d'exécution autonome durant laquelle il n'aura pas besoin d'accéder aux contrôleurs de mémoire.

La période séparant deux instants consécutifs auxquels chaque cœur change de rôle définit une tranche d'exécution notée T. Ensuite, à l'instant 205-j, le premier cœur transmet des données mémorisées dans sa mémoire cache vers le contrôleur de mémoire (référence 225) puis reçoit des données et des instructions du contrôleur de mémoire qu'il mémorise dans sa mémoire cache (référence 230). A partir du même instant 205-j, le second cœur exécute les instructions préalablement mémorisées dans sa mémoire cache avec les données correspondantes (référence 235).

A nouveau, à l'instant 205-k, le premier cœur exécute les instructions préalablement reçues tandis que le second cœur transmet et reçoit des données et des instructions.

Un mécanisme similaire est mis en œuvre dans tous les cœurs. Comme indiqué précédemment, le SoC comprenant le processeur dont le fonctionnement est illustré sur la figure 2 comprend également, de préférence, deux contrôleurs de mémoire. Ainsi, les deux paires de cœurs 240 et 245 de l'ensemble 250 accèdent chacune à un contrôleur de mémoire différent de telle sorte qu'au sein de cet ensemble, chaque contrôleur de mémoire n'est accédé, à un instant donné, que par un seul cœur. De façon similaire, les deux paires de cœurs 255 et 260 de l'ensemble 265 accèdent chacune à un contrôleur de mémoire différent de telle sorte qu'au sein de cet ensemble, chaque contrôleur n'est accédé, à un instant donné, que par un seul cœur. Ainsi, à un instant donné, chaque contrôleur de mémoire est accédé par deux cœurs distincts.

Il convient de remarquer ici que si le SoC dispose de plusieurs contrôleurs de mémoire, l'accès des cœurs à chacun des contrôleurs de mémoire est avantageusement équilibré. Cependant, un seul contrôleur de mémoire peut être utilisé, notamment s'il suffit à servir les besoins de performance du CPM TC. Dans ce cas, l'utilisation d'un seul contrôleur de mémoire permet d'améliorer les coûts de développement ainsi que la fiabilité, la masse et la dissipation thermique du SoC.

L'ordonnancement des phases de transfert sur l'ensemble des coeurs est, de préférence, strictement synchrone, équilibré et planifié. L'usage des ressources partagées, notamment des contrôleurs de mémoire, est également, de préférence, strictement synchrone, équilibré et planifié. Ainsi, si le SoC contient deux contrôleurs de mémoire, la moitié des cœurs en phase de transfert accède, à tout instant, à l'un des contrôleurs de mémoire et l'autre moitié à l'autre contrôleur de mémoire. Si nécessaire, à des instants prédéfinis, tout ou partie des cœurs en phase de transfert peut changer de contrôleur de mémoire afin de maintenir l'exact équilibre. Deux stratégies peuvent être mise en œuvre :

- dédier un seul contrôleur de mémoire par tranche d'exécution, une tranche d'exécution représentant l'ensemble des instructions exécutées par un cœur entre deux points de rendez-vous consécutifs. Cependant, dans ce cas, la tranche d'exécution ne peut pas participer à des processus de calcul mettant en œuvre des fonctions particulières utilisant l'autre contrôleur de mémoire. Une telle stratégie conduit à la création de domaines de calculs propres à chaque contrôleur de mémoire, avec une problématique de communication entre les contrôleurs de mémoire qui peut s'avérer délicate à gérer, notamment pour les I/O utilisant un cœur particulier ; et, - obliger chaque tranche d'exécution à communiquer de façon équitable avec chaque contrôleur de mémoire. Une telle contrainte d'équilibrage n'est pas difficile à atteindre. Les données sont généralement privées pour chaque tranche d'exécution. En outre, elles peuvent être dupliquées si nécessaire, tout comme les instructions. Par ailleurs, ces données peuvent être placées indifféremment sur l'un ou l'autre contrôleur de mémoire pour équilibrer le partage. Bien que le partage d'un contrôleur de mémoire entre deux cœurs ne soit pas une solution optimale vis-à-vis du cœur, cette solution est néanmoins préférable vis-à-vis du contrôleur de mémoire car un cœur seul ne peut généralement pas maintenir un pipeline de requêtes suffisamment long pour effacer entièrement la latence des mémoires utilisées. En effet, lorsque P cœurs fonctionnent en tandem, dans la mesure où chaque requête d'accès ne dépend pas de la complétion des N requêtes précédentes, N étant la profondeur du pipeline d'accès d'un cœur (c'est-à-dire la capacité de l'entité appelée Load Store Unit (LSU) en terminologie anglo-saxonne), le pipeline formé dans le contrôleur de mémoire a une longueur PxN qui permet d'atteindre l'optimum d'efficacité des mémoires utilisées (souvent considérées comme étant l'un des goulets d'étranglement majeur dans un système multi-cœurs).

A titre d'illustration, pour des cœurs disposant d'un pipeline de 5 (LSU), deux cœurs forment un pipeline de 10 requêtes dans le contrôleur de mémoire, soit 80 transferts de données de type burst de 8 données par requête. II suffit ainsi que la latence d'une requête soit inférieure à 40 cycles, en utilisant un taux de transfert double {double data rate) pour ne pas avoir de période d'inactivité dans le pipeline du contrôleur de mémoire.

Concernant la longueur des tranches d'exécution, c'est-à-dire l'espacement de points de rendez-vous consécutifs, les références de temps suivantes peuvent être identifiées,

- temps le pire pour exécuter les instructions de code chargées en mémoire cache avec ses données associées. Bien que ce temps dépende de la nature de l'application exécutée, il est relativement constant pour des applications avioniques ; et, - temps le pire pour transférer des données modifiées vers les contrôleurs de mémoire à partir des mémoires caches et pour charger, depuis les contrôleurs de mémoire, les instructions, constantes et variables d'une tranche d'exécution dans les mémoires caches. Ce temps dépend du nombre de cœur en concurrence.

Il convient de remarquer ici que des points de rendez-vous rapprochés sont possibles mais augmentent le nombre de tranches d'exécution et la taille du problème de placement des instructions et de données pour le traitement en tranches d'exécution. Cette fragmentation des traitements augmente aussi le volume total des données à charger et à décharger des mémoires caches.

Alors que les figures 2a et 2b illustrent un exemple de placement optimal lorsque la durée de la phase de déchargement/chargement est identique à celle de la phase d'exécution des instructions, de nombreuses autres répartitions sont possibles. A titre d'illustration, les figures 2c et 2d montrent des exemples de placement optimal lorsque la durée de la phase d'exécution des instructions est inférieure à trois fois celle de la phase de déchargement/chargement et supérieure ou égale à trois fois celle de la phase de déchargement/chargement, respectivement, Δ représentant la durée d'une tranche d'exécution.

La figure 3, comprenant les figures 3a et 3b, illustre un exemple d'architecture multi-cœurs adaptée à mettre en œuvre l'invention. Le système multi-cœurs 300 représenté schématiquement sur la figure 3a comprend ici huit cœurs référencés 305-1 à 305-8 reliés chacun à une mémoire locale à durée d'accès faible, invariante et indépendante de l'historique, c'est-à-dire de l'exécution antérieure de l'unité de calcul à laquelle elle est reliée. Ces mémoires locales portent ici les références 310-1 à 310-8. Elles peuvent être des mémoires caches locales ou des blocs de mémoire statique accessibles par adressage virtuel ou physique depuis les unités de calcul. Chaque mémoire locale est elle-même connectée à une unité de bus, dont les références sont 315-1 à 315-8, connectée à son tour à un bus commun 320 relié à une mémoire partagée 325. Les cœurs forment des unités de calcul arithmétique, logique, flottant ou autre qui exécutent les traitements complexes. Ils n'accèdent qu'à la mémoire locale à laquelle ils sont reliés. La problématique de calcul de WCET des cœurs formant le domaine 330 est décorrélée de la caractéristique multi-cœurs et de la problématique de modélisation de la mémoire externe partagée et du réseau d'interconnexion des cœurs formant le domaine 335. Par ailleurs, les mémoires caches ou blocs de mémoire statique sont maintenus en cohérence et alimentés par un système à plusieurs acteurs plus simple que les cœurs. Notamment, la variabilité due aux entrées, la combinatoire due aux décisions de branchements, toutes les décisions spéculatives que peuvent prendre les unités d'exécution et toute la variabilité due aux incertitudes de synchronisme entre les cœurs sont ignorées du domaine 335. En pratique, du fait de l'absence de variabilité, il peut être considéré qu'une seule mesure suffit à déterminer l'unique temps nécessaire au chargement de chaque tranche. Cette invariabilité n'est cependant obtenue que si les opérations de rafraîchissement de la mémoire sont désactivées et que c'est la périodicité des accès du domaine 335, à chaque page de mémoire, qui assure le maintien de la mémoire partagée.

La problématique WCET du domaine 330 consiste alors seulement à calculer le WCET de programmes arbitrairement complexes, considérés individuellement, pour chacune des tranches de calcul, et indépendamment de la complexité du domaine 335.

Cette décomposition en domaines 330 et 335 peut être atteinte sur des processeurs mono ou multi-cœurs classiques pourvus de mémoires caches et de jeux d'instructions adéquats en synchronisant les unités de bus des cœurs et en leur faisant jouer le rôle du système mis en œuvre pour maintenir la cohérence des mémoires 310-1 à 310-8.

La figure 3b illustre un exemple d'architecture d'un SoC multi-cœurs adapté à mettre en œuvre l'invention.

Le SoC 300' comprend ici les huit cœurs 3O5'-1 à 3O5'-8, génériquement référencés 305, auxquels sont associés des mémoires caches privées génériquement référencées 340, 345 et 350. Par exemple, la mémoire cache L1_l, référencée 340-1 , la mémoire cache L1_D, référencée 345-1 , et la mémoire cache L2, référencée 350-1 , sont associées au cœur 3O5'-1. De façon similaire, la mémoire cache L1_l, référencée 340-8, la mémoire cache L1_D, référencée 345-8, et la mémoire cache L2, référencée 350-8, sont associées au cœur 3O5'-8. Il en est de même pour les autres cœurs.

Chaque système formé d'un cœur et de la mémoire cache privée associée est relié à un bus de données rapide, référencé 320', qui est lui-même relié aux contrôleurs de mémoire 355-1 et 355-2, génériquement référencés 355.

Il convient de remarquer ici que le cœur 3O5'-8 est ici dédié à la gestion des entrées/sorties physiques. A titre d'illustration, les cœurs 3O5'-1 à 3O5'-8 peuvent avoir une fréquence interne de 1 ,6 GHz. Le bus de données reliant les cœurs aux contrôleurs de mémoire peut également utiliser une fréquence de 1 ,6 GHz. Ainsi, si le volume de données échangées entre les contrôleurs de mémoire et les mémoires caches, comprenant les instructions, les données écrites et les données lues, est de 192 Ko, le temps de chargement/déchargement est alors d'environ 25 μs en comptant le partage du canal entre deux cœurs et les contrôleurs de mémoire ainsi qu'au surdébit, appelé overhead en terminologie anglo-saxonne, lié aux descripteurs de configuration de la tranche suivante.

Toujours selon cet exemple, le temps d'exécution des instructions, représentant environ deux tiers des données échangées, avec un ratio d'une instruction par trois cycles d'un cœur, à 1 ,6 GHz, est d'environ 54 μs.

Par ailleurs, les applications nécessitant généralement un espace mémoire supérieur à la capacité des mémoires caches propres à chaque cœur, celles-ci doivent être découpées en plusieurs phases. Chaque phase est traitée dans une tranche d'exécution. Les volumes d'instructions et de données impliquées dans chaque tranche doivent être compatible avec la capacité des différentes mémoires caches. Le découpage doit notamment parvenir à un nombre de tranches aussi réduit que possible, avec des tranches réalisant le plus de traitements possible. Ce découpage est, de préférence, réalisé préalablement à son exécution par un atelier de génération logiciel. La figure 4, comprenant les figures 4a à 4d, illustre un exemple de mécanisme d'accès, par chaque cœur en phase de transfert d'un processeur multi-cœurs, aux contrôleurs de mémoire de ce processeur.

Comme indiqué précédemment, pour ne pas spécialiser les cœurs sur une partie des applications, il est nécessaire de séparer les phases de chargement et déchargement en lots équilibrés sur chaque contrôleur de mémoire. Ce découpage doit aussi séparer les chargements et les déchargements afin de réduire et de simplifier les combinaisons d'accès obtenues en combinant deux cœurs (combinaisons réduites à tous les cœurs en phase de chargement ou à tous les cœurs en phase de déchargement). Une considération importante de la séparation des chargements et des déchargements est la facilité de construire un modèle du fonctionnement des unités de bus des cœurs, du réseau d'interconnexion des cœurs et des contrôleurs de mémoire. Pour les coeurs eux-mêmes, établir un modèle d'unité de bus entrelaçant de façon quelconque les accès mémoire serait très difficile, construire deux demi modèles, un pour les chargements et un pour les déchargements, apparaît plus facile. Ainsi, si un processeur est complexe, il est néanmoins possible de le « simplifier » en considérant son comportement seulement sur un programme simple, ici une séquence de chargement et une séquence de déchargement non corrélés, c'est-à-dire dont la complétion d'une instruction ne bloque pas les instructions suivantes.

Comme illustré sur la figure 4a, dans un premier temps, une première moitié des cœurs en phase de transfert accède au premier contrôleur et la seconde moitié accède au second contrôleur. Ainsi, les cœurs 3O5'-1 et 3O5'-2 accèdent au contrôleur de mémoire 355-2 tandis que les cœurs 3O5'-3 et 3O5'-4 accèdent au contrôleur de mémoire 355-1 et que les cœurs 3O5'-5 à 3O5'-8 sont en phase d'exécution et ne peuvent accéder aux contrôleurs de mémoire 355-1 et 355-2.

Dans un second temps, comme illustré sur la figure 4b, la seconde moitié des cœurs en phase de transfert accède au premier contrôleur et la première moitié accède au second contrôleur. Ainsi, les cœurs 3O5'-1 et 3O5'-2 accèdent au contrôleur de mémoire 355-1 tandis que les cœurs 3O5'-3 et 3O5'-4 accèdent au contrôleur de mémoire 355-2 et que les cœurs 3O5'-5 à 3O5'-8 sont toujours en phase d'exécution et ne peuvent toujours pas accéder aux contrôleurs de mémoire 355-1 et 355-2.

Les premier et second temps illustrés sur les figures 4a et 4b sont répétés de telle sorte que, durant une première période, les contrôleurs de mémoire 355-1 et 355-2 sont utilisés pour le déchargement de données et que, durant une seconde période, les contrôleurs de mémoire 355-1 et 355-2 sont utilisés pour le chargement de données. La première et la seconde période ont ici une durée identique, la durée de la première période étant, comme celle de la seconde, identique pour chaque contrôleur de mémoire.

Ainsi, la séquence d'opérations consiste à décharger toutes les données en croisant les liens entre les contrôleurs de mémoire et les cœurs en phase de transfert à un instant donné puis à charger les nouvelles données en croisant à nouveau les liens entre les contrôleurs de mémoire et les cœurs en phase de transfert à un instant donné.

Ensuite, les cœurs changent de rôle. En d'autres termes, les cœurs qui étaient en phase de transfert passent en phase d'exécution tandis que les cœurs qui étaient en phase d'exécution passent en phase de transfert. Ainsi, dans un troisième temps, comme illustré sur la figure 4c, les cœurs 3O5'-5 et 3O5'-6 accèdent au contrôleur de mémoire 355-2 tandis que les cœurs 3O5'-7 et 3O5'-8 accèdent au contrôleur de mémoire 355-1 et que les cœurs 3O5'-1 à 3O5'-4 sont en phase d'exécution et ne peuvent accéder aux contrôleurs de mémoire 3355-1 et 355-2.

Ensuite, dans un quatrième temps, comme illustré sur la figure 4d, les cœurs 3O5'-5 et 3O5'-6 accèdent au contrôleur de mémoire 355-1 tandis que les cœurs 3O5'-7 et 3O5'-8 accèdent au contrôleur de mémoire 355-2 et que les cœurs 3O5'-1 à 3O5'-4 sont toujours en phase d'exécution et ne peuvent toujours pas accéder aux contrôleurs de mémoire 355-1 et 355-2.

A nouveau, les troisième et quatrième temps illustrés sur les figures 4c et 4d sont répétés de telle sorte que, durant une première période, les contrôleurs de mémoire 355-1 et 355-2 sont utilisés pour le déchargement de données et que, durant une seconde période, les contrôleurs de mémoire 355-1 et 355-2 sont utilisés pour le chargement de données. La première et la seconde période ont ici une durée identique, la durée de la première période étant, comme celle de la seconde, identique pour chaque contrôleur de mémoire. Ainsi, de façon similaire, la séquence d'opérations consiste à décharger toutes les données en croisant les liens entre les contrôleurs de mémoire et les cœurs en phase de transfert à un instant donné puis à charger les nouvelles données en croisant à nouveau les liens entre les contrôleurs de mémoire et les cœurs en phase de transfert à un instant donné. La maîtrise du dénombrement des changements de page au sein des mémoires utilisées impose que deux cœurs ne devraient pas accéder, dans une même phase de transfert, aux même banques. Cela impose des contraintes supplémentaires à deux cœurs travaillant en même temps pour une même application. En pratique, cela impose que deux cœurs n'accèdent pas en même temps à la mémoire utilisée pour une application. Le serveur d'I/O, présenté ci-dessous, est un cas particulier car, par définition, il accède à toutes les applications. L'objectif est alors de placer les accès des applications à leurs I/O à des dates différentes du serveur d'I/O.

Chaque cœur possède, de façon permanente, c'est-à-dire verrouillée en mémoire cache, une instance d'un logiciel de supervision qui a pour objet de séquencer l'ensemble des tranches à exécuter sur le cœur. Par exemple, il réalise, pour chaque tranche d'exécution, les opérations suivantes :

- lecture dans une table de configuration mémorisée dans une mémoire accédée via un contrôleur de mémoire des informations de blocs à charger dans les mémoires caches et des informations à transmettre ;

- chargement des instructions, des constantes et des données dans les mémoires cache ;

- exécution du contenu de la tranche ;

- attente de la fin de la tranche d'exécution ; et, - transmission via les contrôleurs de mémoire des données modifiées. La détermination du cas de transfert le pire peut être effectuée selon deux approches :

- par mesure s'il existe peu de configurations temporelles, qu'il est possible de les mesurer et de prédire, pour chaque séquence d'accès, le temps de chaque accès ; et,

- par construction d'un modèle du système multi-cœurs restreint aux séquences d'instructions dans le logiciel de supervision. Il est alors possible de connaître à tout instant l'état des cœurs. Cette approche suppose cependant que les informations de conception du SoC pour modéliser le processus de transfert soient connues.

Il convient de rappeler ici que, conformément à l'invention, les cœurs n'ont pas accès aux contrôleurs de mémoire durant leur phase d'exécution. En d'autres termes, les cœurs n'ont aucun accès aux adresses non déjà présentes en mémoires caches. La restriction de l'exécution aux seules données et instructions chargées en mémoire cache a ainsi le même effet qu'une programmation de l'unité de gestion de la mémoire, appelée MMU (sigle de Memory Management Unit en terminologie anglo-saxonne), à la granularité des lignes des mémoires caches puisque tout accès en dehors des adresses déterminées par le résultat de placement aurait pour effet de déclencher une exception de violation d'accès.

Si une application est à l'origine d'une erreur dans une mémoire cache, que ce soit par bug, panne ou altération de type SEU (sigle de Single Event Upset en terminologie anglo-saxonne, représentant une altération de l'état d'un bit dans une mémoire ou un registre due au passage d'un rayon cosmique), le coeur est susceptible d'initier un accès aux contrôleurs de mémoires. Cependant, cet accès est dénié et provoque une exception qui est reprise par le logiciel de supervision qui désactive la tranche, le cœur ou l'application à laquelle appartient la tranche. Bien entendu, il est admis ici qu'un tel mécanisme de protection puisse être établi sur le système multi-cœurs. Un SoC explicitement conçu à cet usage offre très simplement cette opportunité.

Alternativement, il est possible, au niveau du système d'arbitrage du bus, de dénier les requêtes des cœurs en exécution. Une autre solution consiste à déclencher une interruption sur un accès bus observé par un moyen normalement dédié au débogage. Il est également possible de cartographier, du côté des cœurs, les contrôleurs de mémoire à des adresses différentes pour des cœurs accédant à la mémoire à des instants différents et de cartographier ensuite physiquement les contrôleurs de mémoire sur les adresses attendues par les cœurs ayant à cet instant l'accès à la mémoire. De façon générale, le plus simple est que le SoC dispose d'un DMA capable de charger dans les mémoires caches ou la mémoire locale de chaque cœur les données dont il a besoin pour la prochaine tranche. Les mémoires caches contiennent, de préférence, soit des données verrouillées indéfiniment, c'est-à-dire des données verrouillées durant toute la durée de la phase temps critique, soit des données verrouillées pour la durée d'une tranche. La mémoire cache la plus proche des cœurs, réservée aux instructions, est verrouillée avec les éléments de code les plus critiques, par exemple une bibliothèque de routines appelées fréquemment. La mémoire cache la plus lointaine contient avantageusement le code applicatif et les tables de constantes les plus volumineuses qui présentent le moindre ratio usage sur volume.

Les données dépendantes des tranches sont chargées dans la mémoire cache à partir d'une table de descripteurs elle-même contenue dans la mémoire accessible via un contrôleur de mémoire et chargée en mémoire cache. Il est possible de construire des tables dont l'excédent, appelé overhead en terminologie anglo-saxonne, ne dépasse pas un pourcent en volume. En fin de tranche d'exécution, la table de descripteurs sert encore à transmettre les données attendues modifiées (opération de flush). Il faut s'assurer également qu'il ne puisse exister d'effet de bord dû aux données non modifiées restées en mémoire cache, par exemple en invalidant globalement les mémoires caches (après sauvegarde si nécessaire dans une autre mémoire cache des données rémanentes verrouillées). A titre d'illustration, les mémoires caches non LRU (sigle de Least Recently Used en terminologie anglo-saxonne) ne garantissent pas que les données de l'ancienne tranche disparaîtront nécessairement au profit des données de la nouvelle tranche. Un point important pour mettre en œuvre l'invention réside dans le bon découpage des instructions et des données pour permettre la construction de tranches de calcul utilisant au mieux les ressources des cœurs. Ainsi, chaque tranche doit, de préférence, satisfaire les conditions suivantes : - l'exécution ne doit pas produire d'erreur dans les mémoires caches c'est-à-dire que toutes les données requises par une tranche d'exécution doivent être disponibles en mémoire cache ;

- les volumes d'instructions et de données doivent respecter les tailles des mémoires caches ; - le temps d'exécution le pire, ou WCET, doit être inférieur à la durée des tranches d'exécution ; et,

- l'exécution doit respecter les contraintes d'ordonnancement.

De plus, les traitements doivent être raisonnablement sécables et non fortement séquentiels, afin de laisser quelques degrés de liberté à la solution de placement, et le ratio entre instructions et données, c'est-à-dire la densité de calcul, doit de préférence être élevé afin que la solution soit efficace. En d'autres termes, lorsque les mémoires caches sont chargées en instructions et en données, il doit être possible aux cœurs d'exécuter un grand nombre d'instructions avant de devoir revenir sur le bus pour mettre à jour leur mémoire cache. Ainsi, par exemple, il est souhaitable de ne pas utiliser de fonction nécessitant de grandes tables de données ce qui aurait pour effet de bloquer une grande partie de la mémoire cache pour seulement quelques instructions.

Cependant, de nombreuses applications avioniques telles que les applications de commande de vol électrique sont écrites sous forme de planches, par exemple de planches SCADE (SCADE est une marque), qui possèdent de telles propriétés. De plus, à l'exception de certaines contraintes temporelles, l'ordonnancement des planches est libre.

Le placement des traitements en tranches est réalisé hors ligne, c'est-à-dire avant l'exécution des tranches, par un outil de la chaîne de génération logicielle. Le principe est de recourir aux différentes méthodes disponibles d'optimisation multi-objectifs sous contraintes afin de résoudre de manière statique un placement d'instructions et de données. Le placement hors ligne des traitements en tranches d'exécution est essentiel pour trouver une solution aussi optimale que possible. Il permet de produire une amélioration du WCET, voire l'obtention du minimum, pour l'application concernée tout en bénéficiant de l'amélioration du déterminisme due aux contraintes de localité des données définies précédemment.

Avantageusement, l'application de résolution de contraintes permet de restreindre les expressions mathématiques à des équations linéaires afin de résoudre le système d'équations et optimiser une fonction (recherche opérationnelle). La solution est ici, de préférence, restreinte aux solutions entières. Une telle solution, appelée programmation linéaire en nombres entiers (PLNE) ou Integer Linear Programming (ILP) en terminologie anglo-saxonne, vise à exprimer un problème par système d'équations et/ou d'inéquations linéaires à solutions (partiellement) entières.

Une résolution de type PLNE peut se faire par la méthode du simplexe que peuvent proposer des outils d'optimisation combinatoire, complétée d'heuristiques pour rendre le problème calculable.

Pour faciliter le travail de l'application de résolution de contraintes, il est préférable de simplifier le problème ou de le découper en plusieurs sous- problèmes plus simples. Selon un mode de réalisation particulier, il est demandé à l'application de résolution de contrainte de choisir une tranche pour chaque planche. L'indice i, variant de 1 à S, désigne ici les numéros de tranches tandis que l'indice j, variant de 1 à N, désigne les numéros de planches aussi appelées nœuds, c'est à dire les fractions insécables de l'application. II est défini une variable booléenne N désignant l'état d'un nœud tel que Nj, i = 1 si le noeud j est placé dans la tranche i et que Nj, i = 0 si le noeud j n'est pas placé dans la tranche i. Nj, i est dit "variable de décision" indiquant la décision de placement du noeud Nj.

Chaque noeud Nj est caractérisé par un volume d'instructions et de constantes de taille importante, appelé L2j, propres au nœud j, à placer en mémoire cache L2 ainsi que par un volume de variables et de constantes de petite taille, appelé L1j, propres au nœud j, à placer en la mémoire cache de données L1 D. Chaque nœud Nj est également caractérisé par une liste des variables partagées avec d'autres nœuds et par un pire temps d'exécution WCETj.

Les constantes de taille importante, par exemple des tables d'interpolation, sont à placer dans la mémoire cache L2 afin de ne pas épuiser la capacité de la mémoire cache L1 D. Le choix du seuil de transition entre les mémoires caches L2 et L1 D est déterminé par l'outil de placement. L'expression des contraintes de taille sur les mémoires caches L2 et L1 D est donnée ici à titre d'exemple et correspond à un placement sur deux ressources ayant des caractéristiques différentes, l'une, rapide pour les données peu abondantes, est à réserver aux données critiques au temps d'exécution tandis que l'autre est à utiliser pour les instructions et les données moins critiques. Ce principe peut être adapté à d'autres répartitions des ressources.

Il est alors nécessaire de prendre en considération les contraintes suivantes, exprimées sous forme d'inéquations linéaires,

- chaque tranche ne doit pas excéder la capacité MAXL2 de la mémoire cache L2 :

=> pour tout i > L2r Ni,, + L2 2 * N 2 ,, + ... + L2 N * N N ,, ≤ MAXL2

N soit, Vi^ LI j X N j 1 ≤ MAXLl

7=1 - chaque tranche ne doit pas excéder la capacité MAXL1 D de la mémoire cache L1 D : => pour tout i, L1 i * Ni,, + U 2 * N 2 ,, + ... + L1 N * N N ,, + RESVL1 D < MAXL1 D

N soit V/,∑Z1 7 x N j1 , + RESVLW ≤ MAXLW

7=1

- chaque tranche ne doit pas excéder un temps maximum d'exécution MAXWCET :

=> pour tout i, WCETi * N υ + WCET 2 * N 2 ,, + ... + WCET N * N N ,, < MAXWCET

N soit VU∑WCET j x N j1 , ≤ MAXWCET

7=1

II est également nécessaire de forcer la solution de placement à inclure une et une seule fois chaque nœud dans chaque tranche, => pour tout j, N j , 1 + N j , 2 + ... + N j ,s = 1

soit, YAJX 1 = I

II convient de noter ici que la mémoire cache L1 D n'est pas seulement utilisée pour les constantes de petite taille et les variables mais également pour les variables partagées entre plusieurs nœuds. La valeur

RESVL1 D représente cet espace. Dans une approche simplifiée du problème, séparant le problème de placement des noeuds du problème de placement des variables, il est conseillé de choisir une valeur fixe aboutissant à une solution réalisable et satisfaisante. Dans une solution combinant l'optimisation du placement des noeuds et des variables, RESVL1 D est choisi comme représentant exactement l'occupation des variables en mémoire cache L1 D.

Lorsqu'une contrainte d'ordonnancement existe entre deux noeuds, par exemple si Nj doit être exécuté avant Nk, la série de contraintes suivante est ajoutée (il existe un Nk,i pour chaque tranche candidate au placement) : pour tout j, k tel que j doit précéder k, pour tout i > 2, N k ,, + N k ,,+i + ...+ N k ,s ≥ N j ,,

soit J> w ≥ #„ l=ι

Ainsi, si Nj est placé dans la tranche i, alors Nk doit aussi être placé dans la tranche i ou dans l'une des suivantes. S'il existe par ailleurs des contraintes interdisant le placement séparé de deux nœuds (noeuds insécables), ils peuvent alors partager la même variable de décision.

Par ailleurs, en plus de partager des variables, les noeuds peuvent partager des constantes. Dans une représentation exhaustive du problème, il est possible d'exprimer de façon précise les décisions de placement de ces constantes. Cependant, le partage des constantes de petite taille n'est en général pas très dimensionnant et ne justifie pas de complexifier le problème. Les constantes de petite taille peuvent être dupliquées, c'est-à-dire trouver des solutions différentes dans chaque tranche, sans coût significatif, en utilisant des emplacements non utilisés dans la répartition des variables en mémoire. Les constantes de taille importante, généralement peu nombreuses, par exemple des tables d'interpolation trigonométriques, justifient néanmoins une recherche d'optimisation.

La variable Cc,i est définie comme égale à un si la constante Cc est référencée dans la tranche i. Dans le cas contraire elle est égale à zéro. Une contrainte sur Cc, i est ajoutée de la façon suivante, pour toute tranche i, pour tout noeud j référençant Cc, Cc,i > Nj, i

Ainsi, à partir du moment où le nœud j utilisant Cc est placé dans la tranche i, Cc,i est forcé à 1. Il convient de remarquer que Cc,i n'est pas réellement une variable de décision, c'est une conséquence de la décision de placement des nœuds Nj.

Les constantes de taille importante étant, par exemple, placées en mémoire cache L2, la contrainte sur la mémoire cache L2 est reformulée de la façon suivante, pour tout i, L2i * N υ + L2 2 * N 2 ,, + ... + L2 N * N N ,, + ... + sizeof(Cc) * Cc,i + ... < MAXL2

soit Vι,∑Z2, x N J>t + ∑sizeof(C c )x C c>ι ≤ MAXL2

7=1 ' c=l où sizeof(Cc) représente la taille de la constante Cc, C étant le nombre de constantes de taille importante.

Le même formalisme peut être appliqué pour toute variable partagée Vv. En d'autres terme, Vv, i = 1 si la variable Vv est référencée dans la tranche i sinon Vv, i = 0.

Une contrainte est également ajoutée sur Vv, i de la façon suivante, pour toute tranche i, pour tout noeud j référençant Vv, Vv, i > Nj, i

Pour restreindre la complexité globale du placement, il est possible de subdiviser le problème en recherchant d'abord une solution de placement des nœuds présentant des critères de regroupement des références aux variables (et constantes) et en recherchant une solution minimisant la somme des Vv, i sur toutes les variables Vv et toutes les tranches i. Il est ainsi nécessaire de minimiser la relation suivante, II convient de remarquer que cette fonction n'a pas pour objet de minimiser le cas le pire de remplissage des tranches. En pratique, minimiser le nombre de références aux variables consiste au contraire à maximiser l'occupation de certaines tranches. Il peut être souhaitable cependant de conserver une certaine marge dans la mémoire cache dans chaque tranche afin d'accepter des modifications du logiciel à placer sans avoir à relancer l'outil de placement et obtenir éventuellement un placement complètement différent du précédent. Ceci est notamment utile dans une optique de qualification et vérification incrémentale où il n'est alors pas nécessaire de tester à nouveau les parties de logiciel non modifiées.

Pour le placement des variables, des variables de décision sont définies de la façon suivante : Mv, b = 1 si la variable Vv est placée dans le bloc b sinon Mv,b = 0, b étant un index de bloc variant de 1 à B (un bloc est ici une ligne de mémoire cache ou un groupe de lignes de mémoire cache). Plus les blocs sont grands, plus il est difficile de trouver des placements utilisant efficacement l'espace des blocs. Par contre, la complexité du problème est réduite (moins de variable de décision) et l'efficacité des opérations de mémoire cache améliorée.

Il en résulte les contraintes suivantes, exprimées sous forme d'équations linéaires :

- ne pas allouer de variables dans un bloc au-delà de sa capacité MAXBLOC, => pour tout bloc b, s/zeof(Vi) * Mi ιb + ... + taille(V v ) * M v ,b + ... ≤ MAXBLOC

NbVar soit Vb, ∑sizeof(V v )xM v b ≤ MAXBLOC v=l - allouer chaque variable une et une seule fois,

=> pour toute variable Vv, M v ,i + ... + M v ,b + ... = 1

soit Vv,∑M v i = l b=\

Le chargement d'un bloc b dans une tranche i est identifié par contrainte de la façon suivante, pour toute variable Vv référencée par tout nœud Nj, Hb,, > M v ,b + N j ,, OÙ,

Hb, i = 0 implique que la tranche i est vide et que le bloc i est aussi vide (ce qui n'est possible que si des tranches et des blocs ont été définis en excès) ; Hb, i = 1 implique qu'il n'existe aucun noeud Nj placé dans la tranche i et accédant à des variables placées dans le bloc b, et donc que le bloc b est non requis par la tranche i ; et

Hb, i = 2 implique qu'il existe au moins un noeud Nj placé dans la tranche i et accédant à au moins une variable Vv placée dans le bloc b, et donc que le bloc b est requis par la tranche i. Pour une optimisation conjointe du placement des nœuds et des variables, il est alors possible de compléter la seconde contrainte évoquée en remplaçant la valeur RESVL1 D par l'allocation de blocs destinés aux variables. Il est alors nécessaire de minimiser la valeur USAGE (où USAGE < MAXL1 D) en respectant les contraintes suivantes, pour tout i, LI 1 * N 1 ,, + LI 2 * N 2 ,, + ...+ L1 N * N N ,, + BLK_SZ * (H 1 ,, + ...+ H B> , - B) < USAGE où BLK_SZ représente la taille d'un bloc.

Minimiser la valeur USAGE a pour effet de rechercher le placement des variables minimisant le cas le pire de remplissage de la mémoire cache L1 D par tranches. Naturellement, un placement sur une zone mémoire monolithique d'instructions et de données conduirait à des formules différentes et un placement sur une hiérarchie mémoire à plus de niveaux aurait été différent encore sans pour autant invalider les principes cités ici.

Pour formuler l'optimisation du placement des variables après le placement des nœuds, c'est-à-dire faire les placements en deux étapes, d'abord les nœuds en optimisant les références aux variables, mais sans optimiser le placement des variables en ligne de mémoires caches, puis le placement des variables en bénéficiant du résultat des nœuds, il est possible de reformuler plus simplement les contraintes selon les règles suivantes, - les variables dont toutes les références ont été placées dans une même tranche peuvent être intégrées à l'espace alloué en mémoire cache L1 D pour les variables et les constantes de petite taille propres aux nœuds de la tranche ; et,

- pour les variables Vv partagées par les tranches i, pour chaque bloc b, la contrainte suivante est définie, Hb, i > Mv,b avec Hb, i = 1 s'il existe au moins une variable Vv référencée pour la tranche i et placée dans le bloc b.

Il est alors nécessaire de rechercher la fonction minimisant USAGE (USAGE < MAXL1 D) en respectant les contraintes suivantes, pour tout i, USAGE_L1 i + BLK_SZ * (H1 ,i +...+ HB,i) < USAGE où USAGE_L1 i est issu du résultat de placement des nœuds, c'est-à-dire,

USAGE_L1 i = L1 i * N υ + LI 2 * N 2 ,, +...+ L1 N * N N ,, + s/zeof(variables partagées uniquement dans i)

Les variables et les constantes de petite taille propres aux nœuds peuvent êtres séparées sans difficulté en blocs modifiés et en blocs non modifiés afin de minimiser le nombre de déchargement (flush) en fin de tranche. Pour optimiser le placement des variables partagées et garantir que la solution respecte la borne maximum du nombre de déchargement (flush), il est nécessaire d'ajouter des contraintes supplémentaires. Ainsi, pour toute variable Vv référencée en écriture par i, pour tout bloc b, WbJ > Mv,b

De plus, pour toute tranche i, la fonction minimisant la valeur USAGE (USAGE < MAXL1 D) est recherchée en respectant les contraintes suivantes : pour tout I, USAGE_W_L1 , + BLK_SZ * (Wi , , +...+ W B, ,) < MAX_FLUSH où la valeur USAGE_W_L1 i est issue du résultat de placement des nœuds et correspond à la taille de toutes les données en modifications dans la tranche i et connues avant la résolution des contraintes de placement des variables.

Quelques simplifications peuvent être apportées aux équations décrites ci-dessus. Par exemple, il est possible de ne calculer qu'une seule décision de placement pour toutes les variables partageant exactement la même liste de tranches référencées. Selon un mode de réalisation particulier, il est possible de simplifier le problème en découpant les nœuds ou les variables en plusieurs sous- ensembles. Ce choix de découpage préalable peut être orienté par le concepteur du logiciel à placer, par exemple parce qu'il sait que son application est composée de trois sous-systèmes largement indépendants, ou par l'outil de placement suivant des heuristiques, par exemple en identifiant des nœuds référençant les même variables. Chaque sous problème fait alors l'objet d'un placement indépendant de ses nœuds et de ses variables propres. Un dernier placement des variables partagées termine la résolution du problème. Par exemple, les nœuds peuvent être découpés en plusieurs sous- ensembles selon des périodicités. Les tranches sont alors ordonnancées à la périodicité des nœuds. Il est également possible de découper la spécification utilisée en blocs fonctionnels relativement indépendants. D'autres alternatives sont possibles, notamment en exprimant un système préalable de contraintes visant à distribuer les nœuds en un petit nombre de sous-systèmes plutôt que de distribuer directement les nœuds dans un grand nombre de tranches.

L'optimum recherché pouvant être dégradé par les heuristiques (choix de simplification) mises en places, des méthodes non exhaustives peuvent être employées afin de résoudre le problème d'optimisation combinatoire que représente le problème de placement.

Tout en conservant les fonctions objectifs précédemment décrites et les contraintes liées à l'architecture mise en œuvre, des méthodes d'optimisation telles que l'algorithme d'estimation de distribution, appelé estimation of distribution algorithm en terminologie anglo-saxonne, les méthodes basées sur le principe d'algorithme évolutionnaire (ou algorithme génétique), les réseaux de neurones ou bien un algorithme à essaim de particules, appelé particle swarm optimizer en terminologie anglo-saxonne, peuvent être utilisées.

L'optimisation combinatoire étant un sujet de recherche fortement exploré et en constante évolution, de nombreuses approches sont disponibles, offrant chacune leurs avantages et inconvénients. S'agissant d'un algorithme d'estimation de distribution, l'idée est ici de rechercher une optimisation de placements de nœuds puis de variables, ou même de variables uniquement, les fonctions objectifs permettant la recherche itérative d'une meilleure solution étant notamment les objectifs de minimalité d'échanges de données entre les tranches et les objectifs de minimisation du temps d'exécution par une localisation très fine des données (minimiser le nombre de lignes de mémoires caches qu'une séquence de calcul doit charger ou décharger au niveau d'une mémoire cache L1 au sein d'une tranche d'exécution). La présence de contraintes de différentes natures peut conduire à envisager une recherche d'optimum s'appuyant sur plusieurs méthodes d'optimisation.

Par exemple, concernant l'application de commande de vol, il est possible de distinguer des objectifs et contraintes visant à améliorer le WCET par une localisation fine des données des contraintes d'ordonnancement et de séquentialité d'ensembles de traitements. Ces dernières présentant plus de difficultés pour un algorithme d'estimation de distribution mais ne concernant pas l'ensemble des traitements, elles peuvent faire l'objet d'un traitement différent. Là encore, l'état de l'art concernant l'optimisation combinatoire permet d'adopter un ensemble de démarches donnant des résultats plus ou moins satisfaisants selon les contraintes de l'application considérée et de l'architecture matérielle envisagée afin d'obtenir le découpage en tranches de calculs recherché.

Selon le système de l'invention, les tranches de calcul n'ont aucun accès aux entrées/sorties, appelées I/O, physiques. Elles ne peuvent accéder qu'aux variables ayant été transférées en mémoire cache par le logiciel de supervision. Ainsi, comme illustré sur la figure 3b, un cœur, ou plusieurs si nécessaire, est de préférence dédié à la gestion des I/O physiques. Ce cœur, appelé cœur I/O, héberge une fonction de type « serveur d'I/O » par opposition aux autres cœurs qui peuvent être considérés comme des « serveurs de calcul ». Le cœur I/O produit les variables correspondant aux entrées déformatées du module et consomme les variables correspondant aux sorties non formatées du module. Si la charge de calcul due aux fonctions de formatage du cœur I/O est trop importante, il est envisageable d'attribuer ces formatages aux cœurs de calcul et de laisser uniquement les transferts de données sur les bus externes du SoC au serveur d'I/O. Vu des cœurs de calcul, le cœur I/O est un cœur producteur et consommateur de données banalisées.

Les activités du serveur d'I/O couvrent les opérations d'accès aux registres physiques et aux contrôleurs de bus, par exemple à des contrôleurs Ethernet, PCIe ou à une mémoire non volatile, et les opérations de vérification et de conversion de données vers les structures et types de données connues des applications. Ces opérations sont définies par des tables de configuration, chargées durant les tranches de transfert, planifiées par l'outil de placement, en même temps que la planification des chargements des tranches de calcul. Le cœur I/O possède son logiciel et certaines données, de façon résidente, et utilise ses phases de transfert pour charger et décharger les valeurs des entrées et sorties proprement dites ainsi que les éléments de table de configuration nécessaires à leur traitement.

Le cœur I/O est, de préférence, le seul cœur ayant accès aux bus de type PCIe, Ethernet ou autre. Etant le seul, et sous réserve que ses accès ne perturbent pas les accès des cœurs de calcul aux contrôleurs de mémoire, le cœur I/O dispose de l'usage de ces bus à temps plein. Par contre, étant banalisé du point de vue des accès aux contrôleurs de mémoire, il dispose de tranches et de plages d'accès strictement statiques, planifiées en même temps que la planification des accès des cœurs de calcul.

Par ailleurs, si des contrôleurs de bus doivent effectuer des transferts de données de type DMA, ils doivent pouvoir atteindre des cibles mémoires sans perturber les cœurs de calcul en phase de transfert. Ainsi, selon un mode de réalisation particulier, un composant mémoire doit être disponible afin que ces transferts DMA puisse être réalisés sans affecter la mémoire utilisée par les cœurs de calcul. Ce composant peut être la mémoire cache, de préférence dans celle du cœur I/O, qui est utilisée comme cible. Ce peut être aussi une autre mémoire cache ou zone mémoire accessible par adressage dans le SoC, éventuellement même un plan de mémoire externe adressé par un contrôleur mémoire dédié.

Les activités du serveur d'I/O sont découpées en tranches d'exécution et de transfert, strictement synchrones, équilibrées et planifiées, comme les activités des cœurs de calcul (ou cœurs applicatifs). Le cœur I/O utilise ses tranches de transfert pour lire les tables de configuration, déposer les entrées en mémoire et récupérer les sorties. Les tranches d'exécution sont dédiées au pilotage des contrôleurs de bus. La distribution des opérations par tranche est réalisée par l'outil hors ligne de placements décrit précédemment, dans le respect des capacités de traitement du cœur I/O et des contrôleurs de bus, en cohérence de temps avec les applications.

A ces fins, l'architecture du SoC doit offrir une ségrégation suffisante de chemins pour les échanges entres le cœur I/O et les contrôleurs de bus durant les tranches d'exécution pour éviter d'interférer avec les échanges entre la mémoire et les cœurs de calcul en phase de transfert.

Les entrées physiques du serveur d'I/O peuvent être classées en deux familles :

- les entrées synchrones des applications qui sont acquises sur l'initiative des applications et qui peuvent être placées à temps dans des tranches du serveur d'I/O. Ces entrées consistent généralement en la lecture d'un ou de plusieurs registres pour recevoir une information ; et,

- les entrées asynchrones des applications qui sont acquises selon des événements extérieurs, non corrélés avec l'exécution des applications. Leur acquisition ne peut donc être planifiée de façon entièrement déterministe comme les traitements applicatifs ou les entrées synchrones. Ces entrées consistent généralement en trames ou messages reçus sur des bus numériques tel qu'Ethernet.

Seules les sorties synchrones, c'est-à-dire les sorties émises ou générées sur l'initiative des applications, sont ici considérées. Cependant, pour les éventuelles sorties asynchrones, par exemple une sortie d'un dispositif interrogé par le contrôleur d'un bus asynchrone du séquencement des tranches, il est possible de considérer que le dispositif dispose d'une boîte aux lettres conservant les données déposées. La dépose de données en boîte aux lettres est synchrone des tranches tandis que l'émission sur le bus est asynchrone.

Ainsi, hormis les entrées asynchrones, il est possible d'établir une planification statique, via l'outil hors ligne, pour déterminer les accès aux tables de configuration, aux variables d'entrées/sorties et les activités de pilotage des contrôleurs d'I/O.

Pour les entrées asynchrones, le serveur d'I/O doit disposer d'un élément de tables de configuration à résidence dans ses mémoires caches privées. Cet élément doit lui permettre de corréler l'arrivée non planifiée de l'événement avec une requête d'accès à une zone mémoire précise, puis d'utiliser ultérieurement une date planifiée d'accès à cette zone pour acquérir, si nécessaire, les éléments supplémentaires de tables de configuration et déposer les données reformatées ou non correspondant à l'événement. Les données brutes doivent être conservées en mémoire cache entre l'instant d'arrivée et l'ouverture de l'accès mémoire. L'arrivée de l'événement est non planifiée dans le sens où l'instant auquel il doit arriver est inconnu. Cependant, l'existence même de l'événement est planifiée des adresses en mémoire et des opportunités d'accès planifiés à la mémoire lui ont été attribuées. Si les tranches d'exécution sur les cœurs de calcul sont regroupées de façon à ce qu'une seule application soit active à la fois sur l'ensemble des cœurs, il est possible de réserver sur le serveur d'I/O une tranche prologue pour les entrées et une tranche épilogue pour les sorties de façon à ce que le serveur d'I/O puisse être considéré pendant toute cette durée à l'usage exclusif de l'application active. Cette alternative selon laquelle tous les cœurs sont dédiés à une application pendant une durée déterminée, c'est-à-dire plusieurs tranches, nécessite que soient résolu les problèmes de déterminisme des contrôleurs de mémoire dus aux changements de page. Il peut l'être, par exemple, par l'utilisation d'un modèle suffisamment précis des contrôleurs de mémoire appliqué aux listes de transferts mémoire requis par chaque tranche. Cette alternative nécessite également que les applications ainsi distribuées disposent d'une liberté d'ordonnancement suffisante pour pouvoir être distribuées efficacement sur tous les cœurs de façon parallèle.

Alternativement, la mixité des applications sur les différents cœurs de calcul peut être autorisée. Dans ce cas, les tranches du serveur d'I/O précédant ou suivant les tranches de calcul sont dotées de ressources de temps CPU et d'accès bus statiques (équivalents à des micropartitions). Ces ressources sont connues de l'outil de placement des applications de façon à ce que celles-ci n'excèdent pas leurs ressources attribuées.

Si le SoC dispose de plusieurs contrôleurs Ethernet, il est possible de réaliser des entrées/sorties AFDX ou Erebus de façon logicielle. Ces implémentations doivent cependant rester compatibles avec les contraintes de staticité et de déterminisme nécessaires au découpage en tranches de calcul.

A ces fins, les contrôleurs Ethernet ne doivent pas accéder à la mémoire centrale utilisée par les cœurs de calcul et doivent travailler avec une mémoire et des ressources bus indépendantes. Les ressources type bus peuvent éventuellement être partagées s'il existe une gestion de priorités « instantanée » capable de servir les requêtes des coeurs applicatifs sans préemption, or retard observable, en cas de conflit, avec les accès des contrôleurs Ethernet ou le serveur d'I/O, et sans mettre en défaut les analyses WCET du serveur d'I/O. Cette approche implique que les accès des contrôleurs Ethernet puissent être transparents vis-à-vis des cœurs de calcul. Pour des raisons de performance, il est aussi souhaitable que les données écrites par les bus externes, par exemple Ethernet ou PCIe, soient transférées dans la mémoire locale du serveur d'I/O. Ce transfert peut être réalisé soit directement par le DMA du contrôleur Ethernet soit par un mécanisme équivalent à celui utilisé pour le pré-chargement des mémoires caches.

Les opérations d'émission et de réception AFDX sont de préférence adaptées pour être réalisées dans le cœur IO en respectant les contraintes suivantes : - le cœur IO doit respecter le concept de tranches de communication et de tranches de traitement ; - les contrôleurs Ethernet ne doivent pas perturber les contrôleurs de mémoire ni les autres cœurs ; et,

- les mémoires caches du cœur IO étant trop petites pour stocker entièrement la configuration et les variables liées à l'interface AFDX, elles doivent être chargées par portions.

Durant la réception de données, les paquets reçus par les contrôleurs Ethernet sont stockés dans la mémoire du cœur 10. Ils sont analysés au fur et à mesure de leur réception puis transférés dans d'autres files d'attente. Une table de configuration résidant dans la mémoire locale du serveur d'I/O est utilisée pour associer les identifiants des liens virtuels (ou VL, sigle de Virtual Link en terminologie anglo-saxonne), appelés VLID, des trames reçues à une ou plusieurs des fenêtres planifiées d'accès à la mémoire pour le serveur d'I/O. Il existe une fenêtre pour déposer la partie applicative de la trame en mémoire et, éventuellement, une ou plusieurs autres fenêtres pour lire les éléments de tables de configuration nécessaires à l'identification et au traitement complet de la trame tels que les adresses IP/UDP (sigle d'Internet Protocol / User Datagram Protocol en terminologie anglo-saxonne) de destination pour l'identification du port de destination, le type et l'adresse de stockage du port en mémoire et les informations de surveillance du réseau. La table de configuration résidant dans la mémoire locale du serveur d'I/O, dont la taille est de l'ordre de quelques kilos octets, est utilisée pour chaque trame Ethernet reçue. La gestion de la redondance et de l'intégrité utilise avantageusement des ressources également conservées dans la mémoire locale du serveur d'I/O. Si la recherche des ports nécessite une table trop grande pour être stockée en mémoire locale, les éléments de cette table, nécessaires au traitement du VL identifié par la table de configuration résidant dans la mémoire locale du serveur d'I/O, sont chargés dans les tranches de lecture mémoire du serveur d'I/O autorisées à ce VL et seuls les paquets en attente correspondant à ces VLs sont traités. Si la capacité de la mémoire locale du serveur d'I/O le permet, il est préférable pour des raisons de simplicité et réduction de latence de laisser à résidence ces tables dans le serveur d'I/O. Les activités d'émission du serveur d'I/O sont planifiées par l'outil de placement utilisé pour le placement des traitements applicatifs dans les tranches et pour le placement des tranches sur les cœurs. Durant l'émission, la configuration associée à un VL est chargée dans la mémoire locale au cycle planifié, ainsi que l'état des ports qui lui sont associés. Si les conditions d'émission sont respectées, l'émission est déclenchée dans le cycle à un instant définit par la configuration. De façon similaire, si la mémoire locale du serveur d'I/O le permet, il est préférable de laisser à résidence les tables de configuration nécessaires aux émissions. La figure 5 illustre schématiquement un CPM, dont l'architecture est fondée sur un processeur multi-cœurs tel que celui présenté sur la figure 3b, adapté à mettre en œuvre l'invention où les fonctions AFDX sont gérées de façon logicielle dans le processeur multi-cœurs.

Comme illustré, le CPM 500 comprend le processeur multi-cœurs 505 ayant ici, en particulier, huit cœurs et deux contrôleurs de mémoire. Ces contrôleurs de mémoire sont utilisés comme interface entre les cœurs et les mémoires 510-1 et 510-2. Le CPM 500 comprend en outre une mémoire 515, par exemple une mémoire flash, pour stocker, par exemple, certaines des applications devant être exécutées par les cœurs du processeur 505. Le CPM 500 comprend en outre une interface réseau pour recevoir et transmettre des données, en particulier une interface AFDX, ainsi que la logique nécessaire au fonctionnement du CPM. La fonction AFDX est ici réalisée par le processeur multi-cœurs, c'est-à-dire de façon logicielle.

Naturellement, pour satisfaire des besoins spécifiques, une personne compétente dans le domaine de l'invention pourra appliquer des modifications dans la description précédente.