Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial Internet of Things >> Embarqué

Maîtriser les défis de la programmation et du débogage multicœurs

Dans cet article, nous discuterons de divers aspects du traitement multicœur, y compris un aperçu des différents types de processeurs multicœurs et des raisons pour lesquelles ces appareils deviennent courants et populaires aujourd'hui. Nous examinerons ensuite certains des défis introduits par le fait d'avoir plus d'un cœur sur une puce, et comment les débogueurs modernes prenant en charge le multicœur peuvent aider à rendre ces tâches complexes plus gérables.

Performances des systèmes

Il existe de nombreuses façons d'augmenter les performances d'un système informatique embarqué, allant des algorithmes de compilateur intelligents aux solutions matérielles efficaces. Les optimisations du compilateur sont importantes pour obtenir la planification d'instructions la plus efficace à partir d'un code de langage de haut niveau facile à lire et à comprendre. En plus de cela, les systèmes peuvent tirer parti du parallélisme disponible dans le projet pour traiter plusieurs choses à la fois. Et bien sûr, la mise à l'échelle de la fréquence d'horloge peut être un moyen efficace d'obtenir plus de performances de votre système informatique.

Malheureusement, l'époque où l'on pouvait supposer que les vitesses d'horloge augmentaient géométriquement est révolue. Et l'optimisation du code ne peut vous apporter que tant d'améliorations, en particulier maintenant, après de nombreuses générations de développement de la technologie du compilateur. Cela nous laisse considérer le parallélisme comme la meilleure opportunité de continuer à faire évoluer les performances de notre système au fil du temps.

Parallélisme

Creuser un puits est une tâche difficile à paralléliser. D'autres peuvent aider en déblayant la terre, mais le creusement du trou est généralement le travail d'une seule personne. En conséquence, ajouter plus de personnes dans le trou ne fera pas le travail plus rapidement. En fait, les autres peuvent simplement gêner et ralentir le processus. Certaines tâches ne sont pas adaptées à la parallélisation.

D'autres tâches sont facilement parallélisées. Creuser un fossé est une tâche adaptée à la parallélisation. De nombreuses personnes peuvent travailler côte à côte.

Cette image montre une forme de parallélisme appelé MIMD, Multiple Instruction Multiple Data. Chaque pelleteuse est une unité distincte et peut effectuer différentes tâches. Dans ce cas, vous pouvez imaginer que quatre pelleteuses peuvent faire le travail en environ 1/4 ème le temps d'un seul creuseur.

Avec SIMD, Single Instruction Multiple Data, une seule pelleteuse peut utiliser une pelle comme celle-ci.

L'unité SIMD ne peut faire qu'un seul type de calcul à la fois, mais elle peut le faire sur plusieurs données en parallèle. Ces types d'instructions sont courants dans les unités de traitement vectoriel de nombreux processeurs. Ceci est utile si vos données sont très régulières et que vous devez refaire les mêmes opérations encore et encore sur un ensemble de données volumineux comme dans le traitement d'images. Cependant, pour des tâches de calcul plus générales, ce modèle manque de flexibilité et n'apportera pas de gains de performances.

Cela nous conduit au choix de mettre plusieurs sous-systèmes CPU complets sur une seule puce, créant ainsi des processeurs multicœurs. Plusieurs cœurs sur une seule puce peuvent faire évoluer les performances. Chaque cœur est un processeur complet et peut fonctionner indépendamment ou de concert avec d'autres cœurs.

Différents types de traitement multicœur

Il existe différentes combinaisons de types de cœurs que vous pourriez avoir sur une puce de processeur ainsi que la façon dont le travail est réparti entre eux.

Les processeurs multicœurs homogènes ont deux ou plusieurs copies du même cœur de processeur. Chaque cœur fonctionne de manière autonome et peut communiquer et se synchroniser avec d'autres cœurs via un certain nombre de mécanismes tels que la mémoire partagée ou les systèmes de boîte aux lettres. Chaque processeur a ses propres registres et unités fonctionnelles, et peut avoir sa propre mémoire locale ou cache. Cependant, ce qui rend cela homogène, c'est le fait que tous les cœurs que nous examinons sont du même type.

Un autre type de puce multicœur est appelé multicœur hétérogène avec au moins deux types différents de cœurs de processeur. Ici, les noyaux peuvent avoir des caractéristiques très différentes qui les rendent bien adaptés aux différentes parties des besoins de traitement du système. Un exemple pourrait être une puce de communication Bluetooth où un cœur est dédié à la gestion de la pile de protocoles Bluetooth tandis que l'autre cœur peut gérer les communications externes, le traitement des applications, l'interface humaine, etc. Ce type de puce à cœurs multiples peut être utilisé pour des applications qui ont besoin des deux. performances dédiées en temps réel sur un cœur et capacités de gestion du système sur l'autre.

Voyons maintenant comment les noyaux sont utilisés. Le multitraitement symétrique (SMP) se produit lorsque vous avez plusieurs cœurs et que les cœurs exécutent la même base de code de projet. Différents cœurs peuvent exécuter différentes parties du code en même temps, mais le code est construit en tant que projet unique et est envoyé aux cœurs séparés par un programme de contrôle tel qu'un système d'exploitation en temps réel (RTOS). Par nécessité, les cœurs fonctionnant de cette manière doivent être du même type puisqu'ils utilisent tous le même code de projet compilé pour un type de processeur.

Le multitraitement asymétrique (AMP) se produit lorsque vous disposez de plusieurs cœurs ou processeurs et que chaque processeur exécute sa propre application de projet. Les cœurs séparés peuvent se synchroniser ou communiquer de temps en temps, mais ils ont chacun leur propre base de code qu'ils exécutent. Puisqu'ils mènent chacun leur propre projet, ces cœurs peuvent être de types différents, ou des cœurs hétérogènes. Cependant, ce n'est pas une exigence. Si au moins deux cœurs du même type exécutent un code de projet différent, ce sont des cœurs homogènes, exécutant AMP.

Notez que pour le fonctionnement SMP, vous devez avoir plusieurs cœurs homogènes car ils exécutent tous du code à partir de la même base de code de projet unique. Cependant, si vous avez plusieurs projets avec des bases de code différentes pour les différents cœurs à exécuter, il peut s'agir de cœurs différents, comme dans un système hétérogène. Cependant, si les cœurs sont les mêmes, cela fonctionne aussi.

Raisons d'utiliser le multicœur

Au cours des dernières années, la loi de Moore, inventée au milieu des années 1960, semble enfin s'essouffler, ou du moins ralentir. Les fréquences d'horloge des processeurs ne doublent plus tous les 2-3 ans et, en fait, les processeurs les plus rapides ont atteint un plafond dans la plage des GHz à un chiffre depuis de nombreuses années maintenant.

Une façon de continuer à repousser les limites des performances est d'avoir plus de cœurs de processeur qui fonctionnent ensemble si vous pouvez les utiliser efficacement.

Alors que les vitesses ont atteint un plateau, la taille des transistors a continué de diminuer. Bien que plus lents que par le passé, les petits transistors permettent d'emballer plus de logique sur une seule puce. En conséquence, l'utilisation de ces transistors pour placer plusieurs cœurs de processeur sur une seule puce peut tirer parti d'interconnexions de bus beaucoup plus rapides et plus larges entre les différents sous-systèmes de processeur et de mémoire.

Le multitraitement asymétrique hétérogène est très utile lorsqu'une application a deux charges de travail ou plus qui ont des caractéristiques et des exigences très différentes. L'un peut dépendre du temps réel et de la latence d'interruption, tandis que l'autre peut être plus dépendant du débit que du temps de réponse. Ce modèle fonctionne très bien :par exemple, un appareil peut dédier un cœur à la gestion d'une pile de protocoles de communication comme Bluetooth ou Zigbee, tandis qu'un autre cœur agit comme un processeur d'application exécutant les interactions humaines et les opérations globales de gestion du système. Le processeur de communication, étant isolé, peut fournir une excellente réponse en temps réel requise par la pile de protocoles. De plus, le logiciel de communication peut être certifié selon une norme rendant l'ensemble du produit facile à certifier en séparant les modifications fonctionnelles de cette partie du système.

Défis liés à l'utilisation du multicœur

Quels types de défis sont introduits lorsque vous mettez plus d'un cœur de processeur sur une puce ? Eh bien, creusons-le.

Une application ou un logiciel monolithique peut ne pas être en mesure d'utiliser efficacement les ressources informatiques disponibles. Vous devez organiser l'application en tâches parallèles qui peuvent s'exécuter en même temps pour utiliser les ressources de plusieurs cœurs. Cela peut nécessiter une manière peu familière pour les ingénieurs logiciels de penser à la conception embarquée. La migration du code à boucle unique existant peut ne pas être très facile. Trop peu de threads ou même trop de threads peuvent devenir des obstacles aux performances.

Les applications qui partagent des structures de données ou des périphériques d'E/S entre plusieurs threads ou processus peuvent présenter des goulots d'étranglement en série. Afin de maintenir l'intégrité des données, l'accès à ces ressources partagées peut devoir être sérialisé à l'aide de techniques de verrouillage, par exemple, verrou en lecture, verrou en lecture-écriture, verrou en écriture, verrou tournant, mutex, etc. Des verrous conçus de manière inefficace pourraient créer des goulots d'étranglement en raison de conflits de verrouillage élevés entre plusieurs threads ou processus essayant d'acquérir le verrou pour utiliser une ressource partagée. Cela pourrait potentiellement dégrader les performances de l'application ou du logiciel. Les performances d'une application peuvent même se dégrader à mesure que le nombre de cœurs ou de processeurs augmente si certains cœurs bloquent d'autres en attente de verrous communs, ce qui fait que deux cœurs fonctionnent moins bien qu'un.

Une charge de travail inégalement répartie peut être inefficace dans l'utilisation des ressources informatiques. Vous devrez peut-être diviser les tâches volumineuses en tâches plus petites pouvant être exécutées en parallèle. Vous devrez peut-être remplacer les algorithmes série par des algorithmes parallèles pour améliorer les performances et l'évolutivité. Cependant, si certaines tâches s'exécutent très rapidement et que d'autres prennent beaucoup de temps, les tâches rapides peuvent passer beaucoup de temps à attendre que les tâches longues se terminent. Cela entraîne une inactivité de ressources de calcul précieuses et une mauvaise mise à l'échelle des performances.

Un RTOS vous aidera probablement mais ne résoudra peut-être pas tout. Dans un système SMP, cela est pratiquement indispensable pour planifier des tâches sur un certain nombre de cœurs similaires. Le travail à effectuer peut être divisé par données ou par fonction. Si vous divisez les choses par blocs de données, chaque thread peut effectuer toutes les étapes d'un pipeline de traitement. Alternativement, vous pouvez demander à un thread d'effectuer une étape de la fonction, tandis qu'un autre s'occupe de l'étape suivante, etc. Les avantages d'une technique par rapport à l'autre dépendront des caractéristiques du travail à effectuer.

Débogage dans des environnements multicœurs

La première chose qui est utile lors du débogage d'un système multicœur est la visibilité de tous les cœurs. Idéalement, nous devrions être en mesure de démarrer et d'arrêter les cœurs simultanément ou individuellement, c'est-à-dire, en une seule étape, un cœur pendant que les autres sont en cours d'exécution ou arrêtés. Les points d'arrêt multicœurs peuvent être très utiles pour contrôler le fonctionnement d'un cœur en fonction de l'état d'un autre.

La trace multicœur peut être très difficile à mettre en œuvre. Gérer la bande passante élevée des informations de trace à partir de plusieurs cœurs, ainsi que traiter des types de données de trace potentiellement différents à partir de différents types de cœurs est un véritable défi.


(Source :IAR Systems, schéma avec l'aimable autorisation d'Arm Ltd.)

Voici un exemple de processeur avec des implémentations multicœurs à la fois hétérogènes et homogènes. Il existe deux groupes centraux homogènes, l'un basé sur un double Arm Cortex-A57 et l'autre sur un quad Cortex-A53. Ces groupes sont homogènes en eux-mêmes mais hétérogènes entre les deux groupes.

L'architecture de débogage CoreSight fournit des protocoles et des mécanismes pour communiquer avec les ressources de débogage sur tous les cœurs et il incombe au débogueur de gérer toutes ces informations et d'analyser les messages des différents cœurs. Les interfaces de déclenchement croisé et la matrice (CTI, CTM) permettent l'arrêt simultané des deux cœurs, le déclenchement de la trace et plus encore. L'infrastructure de trace comprend les ports de trace série (SWD) et parallèle (TPIU) utilisés pour lisser le flux de trace, et les entonnoirs de trace qui combinent la trace de chaque source en un seul flux. Par rapport à la partie dual-core, le schéma présenté représente une puce beaucoup plus complexe à contrôler.

Le débogueur C-SPY dans IAR Embedded Workbench prend en charge le débogage multicœur symétrique et asymétrique. Ceci est activé via les options du débogueur sur l'onglet multicœur. Pour activer le débogage multicœur symétrique, il suffit de saisir le nombre de cœurs pour que le débogueur sache avec combien de processeurs différents communiquer. D'autres IDE peuvent avoir des options similaires disponibles.

Sur la droite (ci-dessus), vous pouvez voir une vue dans le débogueur où un cluster Cortex-A9 SMP à 4 cœurs a l'état de ses cœurs affiché avec le cœur numéro 2 arrêté pendant que les trois autres cœurs sont en cours d'exécution.

Un système multicœur asymétrique peut utiliser une partie multicœur hétérogène, comme le ST STM32H745/755 qui a un cœur Cortex-M7 et un Cortex-M4 séparé. Dans ce cas, lorsque le débogueur s'exécute, il utilise deux instances de l'IDE (Master et Node). Un pour chaque cœur, car les deux cœurs exécutent un code de projet différent.

Dans chaque instance de l'IDE, il existe des informations d'état sur le cœur contrôlé ainsi que sur l'autre cœur contrôlé dans l'autre fenêtre. Il existe des options qui peuvent être sélectionnées pour contrôler le comportement du débogueur afin que le démarrage et l'arrêt des cœurs ensemble ou séparément soient sous le contrôle du développeur.

Ce contrôle total est possible grâce aux interfaces de déclenchement croisé (CTI) et à la matrice de déclenchement croisé (CTM) qui forment ensemble la fonction de déclenchement croisé intégrée à Arm. Il existe trois composants CTI, un au niveau du système, un dédié au Cortex-M7 et un dédié au Cortex-M4. Les trois CTI sont connectés les uns aux autres via le CTM comme illustré dans la figure ci-dessous. Les CTI de niveau système et Cortex-M4 sont accessibles au débogueur via le port d'accès système et l'APB-D associé. Le Cortex-M7 CTI est physiquement intégré dans le noyau Cortex-M7 et est accessible via le port d'accès Cortex-M7.


(Source :IAR Systems, diagramme avec l'aimable autorisation de STMicroelectronics du manuel de référence M0399)

Les CTI permettent à des événements provenant de diverses sources de déclencher une activité de débogage et de suivi. Par exemple, un point d'arrêt atteint dans l'un des cœurs de processeur peut arrêter l'autre processeur, ou une transition détectée sur une entrée de déclenchement externe peut être définie pour démarrer la trace de code.

Dans cet exemple avec un processeur multicœur hétérogène qui a un cœur Cortex-M7 et un cœur Cortex-M4 sur une seule puce, deux programmes distincts sont utilisés :l'un pour s'exécuter sur le Cortex-M4 et l'autre sur le Cortex-M7. Chaque projet utilise FreeRTOS pour gérer le logiciel exécuté sur les processeurs. Les deux cœurs communiquent via une interface de mémoire partagée. Cependant, les applications utilisent toutes les deux les mécanismes de transmission de messages FreeRTOS pour communiquer avec l'autre processeur et masquer la complexité des mécanismes sous-jacents. Ainsi, du point de vue d'un processeur, il s'agit simplement d'envoyer ou de recevoir des messages avec une autre tâche. Il est clair que l'autre tâche s'exécute sur un autre cœur de processeur.

L'image ci-dessous est la fenêtre de l'explorateur d'espace de travail dans l'IDE. L'aperçu de deux projets est affiché ici afin que vous puissiez voir le contenu des projets Cortex-M7 et Cortex-M4.

En sélectionnant l'un des autres onglets en bas de la fenêtre, vous pouvez basculer le focus sur le projet M4 ou le projet M7.

Le projet Cortex-M7 a une tâche qui envoie des messages aux tâches exécutées sur le Cortex-M4. Le Cortex-M4 a deux instances d'une tâche de réception en cours d'exécution. Le Cortex-M7 a une tâche de « vérification » qui s'exécute périodiquement pour voir si les choses fonctionnent toujours correctement.

Enfin, le débogueur charge les deux projets. Cela signifie qu'une instance supplémentaire d'Embedded Workbench pour le deuxième débogueur est démarrée.

Pour configurer le débogueur pour la prise en charge du multitraitement asymétrique, nous devons désigner un projet en tant que « Maître » et l'autre en tant que projet « Nœud ». En fait, la sélection est arbitraire et ne détermine quel projet a la capacité de lancer l'autre au démarrage.

Le projet « Node » n'a pas de paramètres spéciaux et ne sait pas qu'il s'exécute en tant que « Nœud » vers un autre projet.

De cette façon, lorsque le projet « Maître » a démarré son débogueur, il lance automatiquement une autre instance de l'EDI pour accueillir une deuxième session de débogueur dans laquelle le deuxième projet s'exécutera.

Résumé

Le multicœur permet des gains de performances lorsque la loi de Moore s'épuise. Cependant, le multicœur présente des défis de débogage et nécessite des approches de développement spécifiques afin que l'application puisse tirer le meilleur parti de l'architecture multicœur.

Une fois la configuration de débogage configurée, le débogage multicœur n'a jamais été aussi simple. Si vous avez déjà utilisé des outils pour déboguer des monocœurs, vous reconnaîtrez tout ce qu'il contient et vous ne comprendrez probablement jamais les autres personnes qui parlent de la difficulté du débogage multicœur pour elles.

Les outils matériels et logiciels modernes vous aideront à surmonter les défis du débogage multicœur.

Remarque :les images des figures sont d'IAR Systems, sauf indication contraire.


Aaron Bauch est ingénieur principal d'applications sur le terrain chez IAR Systems et travaille avec des clients de l'est des États-Unis et du Canada. Aaron a travaillé avec des systèmes et logiciels embarqués pour des entreprises telles qu'Intel, Analog Devices et Digital Equipment Corporation. Ses conceptions couvrent un large éventail d'applications, notamment l'instrumentation médicale, la navigation et les systèmes bancaires. Aaron a également enseigné un certain nombre de cours de niveau collégial, notamment la conception de systèmes intégrés en tant que professeur à la Southern NH University. M. Bauch est titulaire d'une licence en génie électrique de la Cooper Union et d'une maîtrise en génie électrique de l'Université Columbia, tous deux à New York, NY.

Contenus associés :

Pour plus d'informations sur Embedded, abonnez-vous à la newsletter hebdomadaire d'Embedded.


Embarqué

  1. Réseaux Wi-Fi, fournisseurs SaaS et défis informatiques qu'ils posent
  2. Boards – Breakout the Pi – I2C, UART, GPIO et plus
  3. Les cinq principaux problèmes et défis de la 5G
  4. Les facteurs de risque complexes auxquels sont confrontés l'aérospatiale et la défense
  5. 5G, IoT et les nouveaux défis de la Supply-Chain
  6. Relevez les défis ETL des données IoT et maximisez le retour sur investissement
  7. Les 4 principaux défis auxquels est confrontée l'industrie OEM de l'aérospatiale et de la défense
  8. L'importance et les défis d'une documentation à jour
  9. Comprendre les avantages et les défis de la fabrication hybride