Compilation de code en parallèle en utilisant

Compilation de code en parallèle en utilisant

Celui que vous demandez comment créer correctement les logiciels proposera de faire l'une des réponses. Sur les systèmes GNU / Linux, GNU Make [1] est la version open source de la marque originale qui a été publiée il y a plus de 40 ans - en 1976. Make fonctionne avec un makefile - un fichier de texte brut structuré avec ce nom qui peut être mieux décrit comme le manuel de construction du processus de construction de logiciels. Le makefile contient un certain nombre d'étiquettes (appelées cibles) et les instructions spécifiques doivent être exécutées pour construire chaque cible.

En parlant simplement, faire 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 pendant la tape).

Listing 1 montre un exemple de Makefile avec les deux cibles «E1» et «E2» ainsi que les deux cibles spéciales «tous» et «Clean.«L'exécution« 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 «Make All» exécute les instructions pour la cible E1 d'abord et E2 Next. Pour supprimer les fichiers créés précédemment un et deux, exécutez simplement l'appel «Faites nettoyer."

Listing 1

Tout: E1 E2
E1:
toucher un
E2:
toucher deux
faire le ménage:
RM un deux

Faire du courant

Le cas commun 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 de 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 importants. Cette approche n'est plus à jour car la plupart des CPU actuels sont équipés de plus d'un noyau et permettent l'exécution de plus d'un processus à la fois. Avec ces idées à l'esprit, nous examinons si et comment le processus de construction peut être parallélisé. Le but est de simplement réduire le temps de construction.

Faire des améliorations

Il y a quelques options que nous avons - 1) simplifier le code, 2) distribuer les tâches uniques sur différents nœuds informatiques, construire le code et collecter le résultat à partir de là, 3) construire le code en parallèle sur une seule machine, et 4) Combinez les options 2 et 3.

L'option 1) n'est pas toujours facile. Il faut la volonté d'analyser l'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 de processeur.

Option 2) nécessite l'accès à d'autres nœuds informatiques, par exemple, des nœuds informatiques dédiés, des machines inutilisées ou moins utilisées, des machines virtuelles à partir de services cloud comme AWS, ou une alimentation informatique louée à partir de services comme LoadTeam [5]. En réalité, cette approche est utilisée pour créer des packages de logiciels. 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 le discours d'Aysylu Greenberg [16]. DISTCC [2] est un compilateur C dite distribué qui vous permet de compiler le code sur différents nœuds en parallèle et de configurer votre propre système de construction.

L'option 3 utilise la parallélisation au niveau local. Cela peut être l'option avec le meilleur rapport coûts-avantages pour vous, car il ne nécessite pas de matériel supplémentaire comme dans l'option 2. L'obligation d'exécution de la marque en parallèle ajoute l'option -j dans l'appel (abréviation pour -Jobs). Cela spécifie le nombre de travaux exécutés en même temps. La liste ci-dessous demande à faire pour exécuter 4 travaux en parallèle:

Listing 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 nécessaire pour construire la cible 3.

Cependant, il y a un effet secondaire: la sortie des messages d'état pour chaque marque de marque apparaît arbitraire, et celles-ci ne peuvent plus être clairement affectées à une cible. L'ordre de sortie dépend de l'ordre réel de l'exécution du travail.

Définir l'ordre d'exécution

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

* Pour construire la cible «tout», exécutez les instructions pour E1, E2 et E3

* La cible E2 nécessite la construction de la cible E3 avant

Cela signifie que les cibles E1 et E3 peuvent être construites en parallèle, puis E2 suit dès que la construction de E3 est terminée, enfin.

Listing 3

Tout: E1 E2 E3
E1:
toucher un
E2: E3
toucher deux
E3:
toucher trois
faire le ménage:
rm one deux trois

Visualisez les dépendances à faire

L'outil intelligent Make2Graph de MakeFile2Graph [19] Project visualise les dépendances Make comme un graphique acyclique dirigé. Cela aide à comprendre comment les différentes cibles dépendent les unes des autres. Make2Graph sort des descriptions de graphiques au format DOT que vous pouvez transformer en une image PNG à l'aide de la commande dot du projet Graphviz [22]. L'appel est le suivant:

Listing 4

$ faire tout -Bnd | Make2Graph | graphique dot -tpng -o.PNG

Premièrement, la marque est appelée avec la cible «tout» suivi des options «-b» pour construire inconditionnellement toutes les cibles, «-n» (abréviation de «-Dry-run») pour faire semblant d'exécuter les instructions par cible, et « -d "(" -debug ") pour afficher les informations de débogage. La sortie est tuyaux pour faire 2Graph qui tue sa sortie en point qui génère le graphique de fichier image.PNG au format PNG.


Le graphique de dépendance de build 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 travaux 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 les comprend:

  • Bazel [20]
  • CMake [4]: ​​Abréviates multiplateforme ma marque et crée des fichiers de description utilisés plus tard par faire
  • distmake [12]
  • Système de fabrication distribué (DMS) [10] (semble être mort)
  • dmake [13]
  • LSF Make [15]
  • Apache Maven
  • Méson
  • Ninja Build
  • Nmake [6]: Faites Microsoft Visual Studio
  • Pydoi [8]
  • Qmake [11]
  • refaire [14]
  • Scons [7]
  • Waf [9]

La plupart d'entre eux ont été conçus avec une parallélisation à l'esprit et offrent un meilleur résultat concernant le temps de construction que de faire.

Conclusion

Comme vous l'avez vu, il vaut la peine de penser aux constructions parallèles car elle réduit considérablement le temps de construction jusqu'à un certain niveau. Pourtant, il n'est pas facile à réaliser et est livré avec certains pièges [3]. Il est recommandé d'analyser à la fois votre code et son chemin de construction avant d'entrer dans des versions parallèles.

Liens et références

  • [1] GNU Make Manual: Parallel Exécution, https: // www.gnou.org / logiciel / make / manual / html_node / parallèle.html
  • [2] distcc: https: // github.com / distcc / distcc
  • [3] John Graham-Cumming: les pièges et les avantages de GNU font la parallélisation, https: // www.CMCROSSORDS.com / article / pièges et benefits-gin-make-parallélisation
  • [4] Cmake, https: // cmake.org /
  • [5] Loadteam, https: // www.charcuterie.com /
  • [6] nmake, https: // docs.Microsoft.com / en-us / cpp / build / référence / nMake-Reference?View = MSVC-160
  • [7] Scons, https: // www.crisplements.org /
  • [8] Pydoit, https: // pydoi.org /
  • [9] WAF, https: // gitlab.com / ita1024 / waf /
  • [10] Distributed Making System (DMS), http: // www.nongnu.org / dms / index.html
  • [11] Qmake, https: // doc.QT.IO / QT-5 / QMAKE-MANUAL.html
  • [12] Distmake, https: // sourceforge.net / projets / distmake /
  • [13] Dmake, https: // docs.oracle.com / cd / e19422-01 / 819-3697 / dmake.html
  • [14] Redoo, https: // refaire.lecture.IO / EN / DERNIT /
  • [15] LSF Make, http: // sunray2.mit.edu / kits / plate-forme-lsf / 7.0.6/1 / guides / kit_lsf_guide_source / print / lsf_make.pdf
  • [16] Aysylu Greenberg: Building a Distributed Build System at Google Scale, Goto Conference 2016, https: // gotocon.com / dl / goto-chicago-2016 / Slides / Aysylugreenberg_buildingAdSistedBuildSystematGooglescale.pdf
  • [17] Debian Build System, Autobuilder Network, https: // www.Debian.org / devel / buildd / index.en.html
  • [18] Koji - Système de construction et de suivi RPM, https: // pagure.io / koji /
  • [19] Makefile2Graph, https: // github.com / lindenb / makefile2graph
  • [20] Bazel, https: // bazel.construire/
  • [21] Tutorial MakeFile, https: // MakeFileTorial.com /
  • [22] Graphviz, http: // www.graphiquement.org
  • [23] Loi d'Amdahl, Wikipedia, https: // en.Wikipédia.org / wiki / amdahl% 27S_law