GNU-merk

Parallel code compileren met Make

Parallel code compileren met Make

Wie je ook vraagt ​​hoe je software op de juiste manier bouwt, komt met Make als een van de antwoorden. Op GNU/Linux-systemen is GNU Make [1] de open-sourceversie van de originele Make die meer dan 40 jaar geleden - in 1976 - werd uitgebracht. Make werkt met een Makefile - een gestructureerd tekstbestand met die naam dat het best kan worden omschreven als de constructiehandleiding voor het softwarebouwproces. De Makefile bevat een aantal labels (targets genoemd) en de specifieke instructies die moeten worden uitgevoerd om elk doel te bouwen.

Simpel gezegd, Make is een bouwtool. Het volgt het recept van taken uit de Makefile. Hiermee kunt u de stappen op een geautomatiseerde manier herhalen in plaats van ze in een terminal te typen (en waarschijnlijk fouten te maken tijdens het typen).

Lijst 1 toont een voorbeeld Makefile met de twee doelen "e1" en "e2" evenals de twee speciale doelen "alle" en "schoon.Het uitvoeren van "make e1" voert de instructies voor doel "e1" uit en maakt het lege bestand aan. Het uitvoeren van "make e2" doet hetzelfde voor doel "e2" en maakt het lege bestand twee. De aanroep van "make all" voert de instructies uit voor doel e1 eerst en e2 volgende. Om de eerder gemaakte bestanden één en twee te verwijderen, voert u eenvoudig de oproep "make clean" uit.”

Aanbieding 1

alle: e1 e2
e1:
raak er een aan
e2:
twee aanraken
schoon:
rm een ​​twee

Lopend merk

Het gebruikelijke geval is dat u uw Makefile schrijft en vervolgens het commando "make" of "make all" uitvoert om de software en zijn componenten te bouwen. Alle doelen zijn gebouwd in seriële volgorde en zonder enige parallellisatie. De totale bouwtijd is de som van de tijd die nodig is om elk afzonderlijk doel te bouwen.

Deze aanpak werkt goed voor kleine projecten, maar duurt vrij lang voor middelgrote en grotere projecten. Deze aanpak is niet langer up-to-date aangezien de meeste huidige CPU's zijn uitgerust met meer dan één kern en de uitvoering van meer dan één proces tegelijk mogelijk maken. Met deze ideeën in het achterhoofd kijken we of en hoe het bouwproces parallel kan lopen. Het doel is om simpelweg de bouwtijd te verkorten.

Verbeteringen aanbrengen

Er zijn een paar opties die we hebben - 1) vereenvoudig de code, 2) distribueer de afzonderlijke taken naar verschillende computerknooppunten, bouw de code daar en verzamel het resultaat vanaf daar, 3) bouw de code parallel op een enkele machine, en 4) combineer opties 2 en 3.

Optie 1) is niet altijd gemakkelijk. Het vereist de wil om de runtime van het geïmplementeerde algoritme en kennis over de compiler te analyseren, i.e., hoe vertaalt de compiler de instructies in de programmeertaal naar processorinstructies?.

Optie 2) vereist toegang tot andere computerknooppunten, bijvoorbeeld speciale computerknooppunten, ongebruikte of minder gebruikte machines, virtuele machines van cloudservices zoals AWS of gehuurde rekenkracht van services zoals LoadTeam [5]. In werkelijkheid wordt deze aanpak gebruikt om softwarepakketten te bouwen. Debian GNU/Linux gebruikt het zogenaamde Autobuilder-netwerk [17] en RedHat/Fedors gebruikt Koji [18]. Google noemt zijn systeem BuildRabbit en wordt perfect uitgelegd in de talk van Aysylu Greenberg [16]. distcc [2] is een zogenaamde gedistribueerde C-compiler waarmee u code op verschillende knooppunten parallel kunt compileren en uw eigen bouwsysteem kunt opzetten.

Optie 3 maakt gebruik van parallellisatie op lokaal niveau. Dit kan voor u de optie zijn met de beste kosten-batenverhouding, omdat er geen extra hardware voor nodig is zoals bij optie 2. De vereiste om Make parallel uit te voeren, is het toevoegen van de optie -j in de aanroep (afkorting van -jobs). Dit specificeert het aantal taken dat tegelijkertijd wordt uitgevoerd. De onderstaande lijst vraagt ​​aan Make om 4 taken parallel uit te voeren:

Aanbieding 2

$ make --jobs=4

Volgens de wet van Amdahl [23] zal dit de bouwtijd met bijna 50% verkorten. Houd er rekening mee dat deze aanpak goed werkt als de afzonderlijke doelen niet van elkaar afhankelijk zijn; de uitvoer van doel 5 is bijvoorbeeld niet vereist om doel 3 te bouwen.

Er is echter één neveneffect: de uitvoer van de statusberichten voor elk Maak doel lijkt willekeurig en deze kunnen niet langer duidelijk worden toegewezen aan een doel. De uitvoervolgorde is afhankelijk van de werkelijke volgorde van de taakuitvoering.

Definieer uitvoeringsvolgorde maken

Zijn er uitspraken die Make helpen begrijpen welke doelen van elkaar afhankelijk zijn?? Ja! Het voorbeeld Makefile in Listing 3 zegt dit:

* om doel "alles" te bouwen, voer je de instructies uit voor e1, e2 en e3

* target e2 vereist dat target e3 eerder is gebouwd

Dit betekent dat de doelen e1 en e3 parallel kunnen worden gebouwd, eerst, dan volgt e2 zodra de bouw van e3 is voltooid, tenslotte.

Lijst 3

alle: e1 e2 e3
e1:
raak er een aan
e2: e3
twee aanraken
e3:
drie aanraken
schoon:
rm een ​​twee drie

Visualiseer de maak afhankelijkheden

De slimme tool make2graph van het makefile2graph [19]-project visualiseert de Make-afhankelijkheden als een gerichte acyclische grafiek. Dit helpt om te begrijpen hoe de verschillende doelen van elkaar afhankelijk zijn. Make2graph voert grafiekbeschrijvingen uit in dot-indeling die u kunt omzetten in een PNG-afbeelding met behulp van de dot-opdracht van het Graphviz-project [22]. De oproep is als volgt:

Lijst 4

$ alles maken -Bnd | make2graph | punt -Tpng -o grafiek.png

Eerst wordt Make aangeroepen met het doel "all" gevolgd door de opties "-B" om onvoorwaardelijk alle doelen te bouwen, "-n" (afkorting van "-dry-run") om te doen alsof de instructies per doel worden uitgevoerd, en " -d” (“-debug”) om foutopsporingsinformatie weer te geven. De uitvoer wordt doorgesluisd naar make2graph die de uitvoer doorstuurt naar de punt die de afbeeldingsbestandsgrafiek genereert.png in PNG-indeling.


De build-afhankelijkheidsgrafiek voor vermelding 3

Meer compilers en bouwsystemen

Zoals hierboven al uitgelegd, is Make meer dan vier decennia geleden ontwikkeld developed. In de loop der jaren is het parallel uitvoeren van taken steeds belangrijker geworden en sindsdien is het aantal speciaal ontworpen compilers en buildsystemen om een ​​hoger niveau van parallellisatie te bereiken gegroeid. De lijst met tools omvat deze:

De meeste zijn ontworpen met het oog op parallellisatie en bieden een beter resultaat met betrekking tot de bouwtijd dan Make.

Conclusie

Zoals je hebt gezien, is het de moeite waard om na te denken over parallelle builds, omdat dit de bouwtijd tot een bepaald niveau aanzienlijk verkort. Toch is het niet gemakkelijk te bereiken en brengt het bepaalde valkuilen met zich mee [3]. Het wordt aanbevolen om zowel uw code als het buildpad te analyseren voordat u in parallelle builds stapt.

Links en referenties

Hoe een spel op Linux te ontwikkelen
Tien jaar geleden zouden niet veel Linux-gebruikers voorspellen dat hun favoriete besturingssysteem ooit een populair spelplatform voor commerciële vi...
Open source-poorten van commerciële game-engines
Gratis, open source en platformonafhankelijke game-engine-recreaties kunnen worden gebruikt om zowel oude als enkele van de vrij recente gametitels te...
Beste opdrachtregelspellen voor Linux
De opdrachtregel is niet alleen je grootste bondgenoot bij het gebruik van Linux, hij kan ook de bron van entertainment zijn omdat je hem kunt gebruik...