Programmation multicœur avec NI LabVIEW

Aperçu

Le logiciel de programmation graphique NI LabVIEW ne vous fait pas seulement gagner du temps. Il offre de nombreux avantages pour la programmation des processeurs multicœurs et autres matériels en parallèle tels que les FPGA (Field-Programmable Gate Array). Un de ces avantages est la capacité à adapter automatiquement les applications aux microprocesseurs dotés de deux, quatre cœurs ou plus et ce, la plupart du temps, sans effort de programmation supplémentaire. De plus, le code graphique de LabVIEW permet aux ingénieurs et scientifiques de visualiser les opérations en parallèle dans la mesure où il représente de façon naturelle les modèles de programmation en parallèle les plus courants dans l’industrie et l’enseignement.

Contenu

Le défi de la programmation parallèle

La programmation parallèle est indispensable si l’on veut tirer le meilleur parti des processeurs multicœurs. Les processeurs modernes n’ont guère amélioré leurs fréquences d’horloge pour de nombreuses raisons et en particulier à cause de la consommation électrique et de la bande passante de la mémoire. À la place, les fabricants ont commencé à intégrer de multiples cœurs de processeurs sur un même circuit intégré, tout en conservant ou même en réduisant la fréquence d’horloge. De ce fait, au lieu de s’appuyer sur les accélérations de fréquence d’horloge pour améliorer la vitesse des applications, il devient préférable de concevoir des applications qui s’exécutent sur des processeurs multicœurs. À l’avenir, vous risquez de constater des baisses de performances si vous ne prenez pas le temps d’optimiser vos applications pour des processeurs multicœurs.

De nombreux outils ont été optimisés pour relever ce défi et vous permettre de créer du code capable de tirer le meilleur parti des processeurs multicœurs. Vous pouvez attribuer des portions de code à des threads de façon manuelle, que de nombreux systèmes d’exploitation diffusent ensuite à travers différents cœurs de processeurs. Toutefois, la gestion de ces threads est difficile et prend beaucoup de temps. De plus, si différents API et langages annulent une partie des tâches associées aux threads, il est tout de même nécessaire de spécifier les opérations qui peuvent s’exécuter en parallèle.

Figure 1. Les fréquences d’horloge du processeur n’augmentent plus et les performances se situent désormais au niveau des processeurs multicœurs.

Bénéficier des processeurs multicœurs automatiquement

La programmation dans LabVIEW implique la création de code graphique (G) qui ressemble à un organigramme, ce qui diffère de manière significative de la programmation en langages séquentiels traditionnels. On parle alors de programmation par flux de données. Au lieu d’écrire une séquence de commandes à exécuter l’une après l’autre, les programmes LabVIEW contiennent des variables et des opérations connectant chaque variable à la suivante. Le compilateur LabVIEW détermine ensuite automatiquement l’ordre des commandes à exécuter pour produire des résultats corrects. Cela signifie également que, lorsque deux sections parallèles de code ne sont pas interdépendantes, elles peuvent s’exécuter en même temps avec LabVIEW sur les cœurs différents d’un processeur.

Pour visualiser cela, envisagez le programme arithmétique simple illustré par la Figure 2. LabVIEW est capable de reconnaître les fonctions Multiplier, Ajouter et Soustraire et de les exécuter en même temps, car elles ne sont pas dépendantes les unes des autres.

Figure 2. Des chemins de code indépendants s’exécutent simultanément.

Le compilateur LabVIEW identifie de nombreuses sections de code parallèle sur le diagramme et les affecte à un nombre fixe de threads pendant l’exécution. Ainsi, vous n’aurez pas à manipuler les détails des threads manuellement, tout en minimisant la création de nouveaux threads qui pourraient avoir un impact négatif sur les performances.

Création manuelle des threads

La capacité de LabVIEW à gérer les threads automatiquement et à profiter des processeurs multicœurs ne signifie pas que vous perdez le contrôle. Par exemple, vous pouvez vouloir isoler une tâche particulière, telle que la surveillance d’état d’urgence dans un thread à haute priorité dédié. Chaque structure cadencée de LabVIEW, y compris la boucle cadencée, crée un seul thread dans lequel s’exécute le code de la structure, et peut être dirigée vers un cœur spécifique de processeur en paramétrant une option d’affinité du processeur au cours du développement ou pendant l’exécution. Avec LabVIEW, vous vous concentrez sur le problème que vous tentez de résoudre plutôt que de passer du temps sur le mappage du code pour les processeurs multicœurs, sans toutefois renoncer à accéder aux commandes de bas niveau le cas échéant.

Visualisation intuitive du code parallèle

LabVIEW dispose d’un avantage supplémentaire lorsqu’il programme des processeurs multicœurs : la représentation graphique intuitive du code parallèle. Bien que des programmes parallèles puissent être créés avec des langages séquentiels traditionnels, garder la trace des opérations en parallèle représente souvent un défi de taille. De plus, comme les ingénieurs travaillent la plupart du temps en groupe sur des applications de grande taille, le décodage de code parallèle que vous n’avez pas écrit vous-même constitue une tâche encore plus imposante.

Par contre, la programmation LabVIEW par flux de données bénéficie de l’une des formes de communication les plus simples : l’organigramme. Des années durant, les programmeurs en séquentiel ont créé des organigrammes pour garder trace des éléments des programmes et pour communiquer entre eux. Au lieu de transcrire des organigrammes en code séquentiel, et vice-versa, vous avez ici la possibilité d’implémenter directement vos idées en code graphique de flux de données, et d’identifier rapidement les chemins de code parallèle s’exécutant sur des cœurs de processeurs différents.

Le code graphique de LabVIEW représente intuitivement les modèles de programmation parallèle les plus courants de l’industrie et de l’enseignement. Certains modèles populaires incluent la parallélisation des tâches, la parallélisation des données et l’utilisation de pipeline.

Parallélisme des tâches

Le parallélisme des tâches consiste en deux opérations séparées ou plus, exécutables en parallèle. Dans le code LabVIEW, à droite, vous remarquerez que les opérations de filtrage et de transformées de Fourier rapides (FFT) ne sont pas interdépendantes et qu’elles peuvent s’exécuter simultanément sur plusieurs cœurs du processeur.

Parallélisme des tâches

Figure 3. Exemple de parallélisme des tâches

Parallélisme des données

Le parallélisme des données est un modèle de programmation courant qui consiste à séparer une grande quantité de données en deux et à traiter chaque pièce simultanément avant de combiner les résultats. Observez la séparation des voies de données, le traitement et la fusion du code dans l’illustration.

Parallélisme des données

Figure 4. Exemple de parallélisation des données

Utilisation de pipeline

L’utilisation de pipeline représente une chaîne de montage sur laquelle les fonctions sont continuellement répétées et les données transmises à l’opération suivante pour l’itération qui suit. Dans LabVIEW, l’utilisation de pipeline peut être représentée par des unités d’attente, aussi appelées nœuds de rétroaction, entre les opérations.

Utilisation de pipeline

Figure 5. Exemple d’utilisation de pipeline

La plupart des applications pratiques, telles que le traitement de signaux RF et l’analyse d’images, combine ces modèles avec d’autres modèles de programmation parallèle. Vous pourriez, par exemple, implémenter plusieurs pipelines sur un seul diagramme LabVIEW, pour représenter à la fois le parallélisme des tâches et l’utilisation de pipeline. Grâce à LabVIEW, vous pouvez optimiser des applications pour des processeurs multicœurs par le biais de la visualisation intuitive du code parallèle.

Outil puissant de mise au point graphique

La mise au point est un élément important du développement de toute application, et LabVIEW dispose de fonctionnalités de mise au point et de connectivité pour complément logiciel afin d’en savoir plus sur les opérations de programmation parallèle. Par exemple, la fonctionnalité Animer l’exécution de LabVIEW permet de visualiser le déplacement des données entre les opérations et l’exécution simultanée des chemins de code parallèle, mais également de vérifier que le Toolkit Desktop Execution Trace indique la séquence exacte des événements dans l’application. Sur du matériel cible LabVIEW exécutant des systèmes d’exploitation temps réel, le Toolkit NI Real-Time Execution Trace affiche également l’historique complet du programme qui précise le cœur de circuit intégré sur lequel s’exécutent un thread et le détail de son cadencement. Ceci permet d’identifier et de corriger des problèmes tels que l’inversion des priorités, au cas où une tâche prioritaire resterait en attente derrière une tâche secondaire utilisant une ressource partagée. La possibilité de suivre quels threads s’exécutent, quand, où, et sur quel cœur, ainsi que les ressources utilisées, constitue un atout majeur pour ajuster les performances et la fiabilité de l’application.

Résoudre les problèmes d’ingénierie les plus complexes

En plus de la programmation de microprocesseurs multicœurs, vous pouvez utiliser LabVIEW avec d’autres matériels parallèles, y compris les FPGA, unités de traitement graphique et même le cloud computing. Ces plates-formes matérielles possèdent toutes des caractéristiques, des avantages et des compromis uniques, et LabVIEW permet aux ingénieurs et scientifiques de bénéficier de la plate-forme idéale pour chaque application. Du fait que LabVIEW vise ces différents matériels, la programmation graphique peut mener à bien une grande variété de projets, malgré la diversité de leurs exigences de traitement parallèle.

D’ailleurs, les chercheurs travaillant sur certains des problèmes d’ingénierie les plus complexes – depuis la fusion jusqu’au contrôle du plus grand télescope du monde, utilisent LabVIEW avec toute une gamme de matériels parallèles pour leurs applications. En fin de compte, LabVIEW a été conçu pour aider les experts dans de nombreux domaines d’activités à concrétiser leurs idées en programmes fonctionnels rapidement. Puisque LabVIEW est capable de tirer le meilleur parti des processeurs multicœurs automatiquement avec son code graphique intuitif, vous disposez en permanence du matériel parallèle le plus performant pour relever les défis d’ingénierie de la prochaine génération.