Marque GNU

Compiler du code en parallèle à l'aide de Make

Compiler du code en parallèle à l'aide de Make

Celui à qui vous demanderez comment créer un logiciel correctement trouvera Make comme l'une des réponses. Sur les systèmes GNU/Linux, GNU Make [1] est la version Open-Source du Make original qui a été publié il y a plus de 40 ans - en 1976. Make fonctionne avec un Makefile - un fichier texte structuré avec ce nom qui peut être décrit comme le manuel de construction pour le processus de création de logiciels. Le Makefile contient un certain nombre d'étiquettes (appelées cibles) et les instructions spécifiques à exécuter pour construire chaque cible.

En termes simples, Make est un outil de construction. Il suit la recette des tâches du Makefile. Il vous permet de répéter les étapes de manière automatisée plutôt que de les taper dans un terminal (et probablement de faire des erreurs lors de la frappe).

Le listing 1 montre un exemple de Makefile avec les deux cibles « e1 » et « e2 » ainsi que les deux cibles spéciales « all » et « clean."L'exécution de "make e1" exécute les instructions pour la cible "e1" et crée le fichier vide. L'exécution de "make e2" fait de même pour la cible "e2" et crée le fichier vide deux. L'appel de "faire tout" exécute les instructions pour la cible e1 d'abord et e2 ensuite. Pour supprimer les fichiers un et deux précédemment créés, exécutez simplement l'appel "make clean."

Liste 1

tout : e1 e2
e1 :
toucher un
e2 :
toucher deux
faire le ménage:
rm un deux

Faire courir

Le cas courant est que vous écrivez votre Makefile puis exécutez simplement la commande "make" ou "make all" pour construire le logiciel et ses composants. Toutes les cibles sont construites dans l'ordre série et sans aucune parallélisation. Le temps de construction total est la somme du temps nécessaire pour construire chaque cible.

Cette approche fonctionne bien pour les petits projets mais prend assez de temps pour les projets moyens et plus grands. Cette approche n'est plus à jour car la plupart des processeurs actuels sont équipés de plus d'un cœur et permettent l'exécution de plus d'un processus à la fois. Avec ces idées en tête, nous examinons si et comment le processus de construction peut être parallélisé. L'objectif est simplement de réduire le temps de construction.

Faire des améliorations

Nous avons quelques options - 1) simplifier le code, 2) distribuer les tâches individuelles sur différents nœuds de calcul, y construire le code et collecter le résultat à partir de là, 3) construire le code en parallèle sur une seule machine, et 4) combiner les options 2 et 3.

L'option 1) n'est pas toujours facile. Cela nécessite la volonté d'analyser le temps d'exécution de l'algorithme implémenté et des connaissances sur le compilateur, je.e., comment le compilateur traduit-il les instructions du langage de programmation en instructions du processeur.

L'option 2) nécessite l'accès à d'autres nœuds de calcul, par exemple, des nœuds de calcul dédiés, des machines inutilisées ou moins utilisées, des machines virtuelles à partir de services cloud comme AWS ou de la puissance de calcul louée à partir de services comme LoadTeam [5]. En réalité, cette approche est utilisée pour construire des progiciels. Debian GNU/Linux utilise le soi-disant réseau Autobuilder [17], et RedHat/Fedors utilise Koji [18]. Google appelle son système BuildRabbit et est parfaitement expliqué dans l'exposé d'Aysylu Greenberg [16]. distcc [2] est un compilateur C dit distribué qui vous permet de compiler du code sur différents nœuds en parallèle et de mettre en place votre propre système de build.

L'option 3 utilise la parallélisation au niveau local. Cela peut être l'option avec le meilleur rapport coût-bénéfice pour vous, car elle ne nécessite pas de matériel supplémentaire comme dans l'option 2. L'exigence pour exécuter Make en parallèle est d'ajouter l'option -j dans l'appel (abréviation de -jobs). Ceci spécifie le nombre de tâches qui sont exécutées en même temps. La liste ci-dessous demande à Make d'exécuter 4 tâches en parallèle :

Liste 2

$ make --jobs=4

Selon la loi d'Amdahl [23], cela réduira le temps de construction de près de 50%. Gardez à l'esprit que cette approche fonctionne bien si les cibles uniques ne dépendent pas les unes des autres ; par exemple, la sortie de la cible 5 n'est pas requise pour construire la cible 3.

Cependant, il y a un effet secondaire : la sortie des messages d'état pour chaque cible Make semble arbitraire, et ceux-ci ne peuvent plus être clairement assignés à une cible. L'ordre de sortie dépend de l'ordre réel d'exécution du travail.

Définir l'ordre d'exécution

Y a-t-il des déclarations qui aident Make à comprendre quelles cibles dépendent les unes des autres? Oui! L'exemple de Makefile dans le listing 3 dit ceci :

* pour construire la cible « all », exécutez les instructions pour e1, e2 et e3

* la cible e2 nécessite que la cible e3 soit construite avant

Cela signifie que les cibles e1 et e3 peuvent être construites en parallèle, d'abord, puis e2 suit dès que la construction de e3 est terminée, enfin.

Liste 3

tout : e1 e2 e3
e1 :
toucher un
e2 : e3
toucher deux
e3 :
toucher trois
faire le ménage:
rm un deux trois

Visualisez les dépendances de création

L'outil intelligent make2graph du projet makefile2graph [19] visualise les dépendances Make sous la forme d'un graphe acyclique dirigé. Cela permet de comprendre comment les différentes cibles dépendent les unes des autres. Make2graph génère des descriptions de graphiques au format de points que vous pouvez transformer en image PNG à l'aide de la commande dot du projet Graphviz [22]. L'appel est le suivant :

Liste 4

$ faire tout -Bnd | make2graph | point -Tpng -o graphique.png

Tout d'abord, Make est appelé avec la cible "all" suivie des options "-B" pour construire inconditionnellement toutes les cibles, "-n" (abréviation de "-dry-run") pour prétendre exécuter les instructions par cible, et " -d" ("-debug") pour afficher les informations de débogage. La sortie est redirigée vers make2graph qui dirige sa sortie vers un point qui génère le graphique du fichier image.png au format PNG.


Le graphique de dépendance de construction pour la liste 3

Plus de compilateurs et de systèmes de construction

Comme déjà expliqué ci-dessus, Make a été développé il y a plus de quatre décennies. Au fil des ans, l'exécution de tâches en parallèle est devenue de plus en plus importante, et le nombre de compilateurs et de systèmes de construction spécialement conçus pour atteindre un niveau de parallélisation plus élevé a augmenté depuis lors. La liste des outils comprend ceux-ci :

La plupart d'entre eux ont été conçus avec la parallélisation à l'esprit et offrent un meilleur résultat en termes de temps de construction que Make.

Conclusion

Comme vous l'avez vu, cela vaut la peine de penser aux builds parallèles car cela réduit considérablement le temps de build jusqu'à un certain niveau. Pourtant, il n'est pas facile à réaliser et comporte certains pièges [3]. Il est recommandé d'analyser à la fois votre code et son chemin de génération avant de passer aux builds parallèles.

Liens et références

Ajoutez des gestes de souris à Windows 10 à l'aide de ces outils gratuits
Ces dernières années, les ordinateurs et les systèmes d'exploitation ont considérablement évolué. Il fut un temps où les utilisateurs devaient utilise...
Contrôlez et gérez le mouvement de la souris entre plusieurs moniteurs dans Windows 10
Gestionnaire de souris à double affichage vous permet de contrôler et de configurer le mouvement de la souris entre plusieurs moniteurs, en ralentissa...
WinMouse vous permet de personnaliser et d'améliorer le mouvement du pointeur de la souris sur un PC Windows
Si vous souhaitez améliorer les fonctions par défaut de votre pointeur de souris, utilisez un logiciel gratuit WinMouse. Il ajoute plus de fonctionnal...