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.

LabVIEW 8.5 a introduit le planificateur multithread automatique du bureau, connu sous le nom de multitraitement symétrique (SMP), à des systèmes déterministes en temps réel avec des améliorations du module LabVIEW Real-Time.

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.

Pile logicielle « Multicore » avec support Real-Time SMP

Intel a défini quatre couches de la pile logicielle que vous pouvez utiliser pour évaluer la « préparation » du développement multicœur. Gardez à l’esprit que les programmes parallèles ne s’exécutent pas plus rapidement sur les systèmes multicœurs si les bibliothèques et drivers que vous utilisez ne sont pas « adaptés multicœurs » ou si le système d’exploitation ne peut pas équilibrer les tâches sur plusieurs cœurs.

Pile logicielle Signification de « adapté multicœur » Support LabVIEW
Outil de développement Prise en charge du système d'exploitation de votre choix ; l'outil facilite un threading et une optimisation corrects Exemple :  La nature multithread de LabVIEW et les structures permettant une optimisation
Bibliothèques Bibliothèques réentrantes et thread-safe Exemple :  Bibliothèques d'analyse
Drivers de périphériques Les drivers sont conçus pour des performances multithreads optimales. Exemple :  Logiciel driver NI-DAQmx
Système d'exploitation Le système d'exploitation prend en charge le multithreading et le multitasking, et peut équilibrer les tâches Exemple :  Support pour Windows, Mac OS, Linux et les systèmes d'exploitation en temps réel

Figure 6. Description d'une pile logicielle « adaptée multicœurs »

Un exemple sur la couche logicielle du driver de périphérique est le logiciel driver NI-DAQmx. Le NI-DAQ traditionnel (ancien driver) est thread-safe, ce qui signifie que toute la bibliothèque empêche d’autres threads de l’appeler lorsqu’une fonction NI-DAQ est appelée.

À première vue, ce comportement peut sembler logique, car NI-DAQ est utilisé pour contrôler le matériel, qui souvent considéré comme une seule ressource. NI-DAQmx, le driver d’acquisition de données moderne remanié, est réentrant, ce qui signifie que plusieurs tâches d’acquisition de données peuvent s’exécuter en parallèle sans bloquer les threads.

Avec cette approche, le driver peut exécuter plusieurs tâches indépendamment, telles que les E/S analogiques et numériques, en parallèle sur le même périphérique.

Au niveau le plus bas de la pile logicielle, le système d'exploitation, de nombreux fournisseurs de système d'exploitation temps réel (RTOS) ne prennent pas encore en charge l'équilibre automatique des charges des threads sur plusieurs cœurs.

LabVIEW 8.5 apporte le planificateur multithread automatique du bureau, connu sous le nom de multitraitement symétrique (SMP), à des systèmes déterministes en temps réel avec des améliorations du module LabVIEW Real-Time.

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.