Marka GNU

Kompilowanie kodu równolegle za pomocą Make using

Kompilowanie kodu równolegle za pomocą Make using

Ktokolwiek zapytasz, jak poprawnie zbudować oprogramowanie, wymyśli Make jako jedną z odpowiedzi. W systemach GNU/Linux, GNU Make [1] jest wersją Open Source oryginalnego Make, wydanego ponad 40 lat temu - w 1976 roku. Make działa z Makefile - ustrukturyzowanym, zwykłym plikiem tekstowym o tej nazwie, który najlepiej można opisać jako podręcznik budowy procesu tworzenia oprogramowania. Makefile zawiera wiele etykiet (zwanych celami) i konkretne instrukcje potrzebne do wykonania, aby zbudować każdy cel.

Mówiąc najprościej, Make to narzędzie do budowania. Jest zgodny z receptą zadań z Makefile. Pozwala powtarzać kroki w sposób zautomatyzowany, zamiast wpisywać je w terminalu (i prawdopodobnie popełniać błędy podczas pisania).

Listing 1 pokazuje przykładowy plik Makefile z dwoma celami „e1” i „e2” oraz dwoma celami specjalnymi „all” i „clean.” Uruchomienie „make e1” powoduje wykonanie instrukcji dla celu „e1” i utworzenie pustego pliku file. Uruchomienie „make e2” robi to samo dla celu „e2” i tworzy pusty plik dwa. Wywołanie „make all” wykonuje najpierw instrukcje dla celu e1 a następnie e2. Aby usunąć wcześniej utworzone pliki jeden i dwa, po prostu wykonaj wywołanie „make clean.”

Lista 1

wszystkie: e1 e2
e1:
dotknij jednego
e2:
dotknij dwa
czysty:
rm jeden dwa

Bieganie Make

Częstym przypadkiem jest to, że piszesz plik Makefile, a następnie po prostu uruchamiasz polecenie „make” lub „make all”, aby zbudować oprogramowanie i jego komponenty. Wszystkie cele są budowane w kolejności szeregowej i bez zrównoleglania. Całkowity czas budowy to suma czasu wymagana do zbudowania każdego celu.

Takie podejście sprawdza się w przypadku małych projektów, ale w przypadku średnich i większych projektów trwa dość długo. To podejście nie jest już aktualne, ponieważ większość obecnych procesorów jest wyposażona w więcej niż jeden rdzeń i umożliwia wykonywanie więcej niż jednego procesu jednocześnie. Mając na uwadze te pomysły, przyglądamy się, czy i jak proces kompilacji można zrównoleglać. Celem jest po prostu skrócenie czasu budowy.

Wprowadzaj ulepszenia

Mamy kilka możliwości: 1) uprościć kod, 2) rozdzielić pojedyncze zadania na różne węzły obliczeniowe, zbudować tam kod i zbierać wyniki, 3) zbudować kod równolegle na jednej maszynie, oraz 4) połącz opcje 2 i 3.

Opcja 1) nie zawsze jest łatwa. Wymaga woli analizy czasu wykonania zaimplementowanego algorytmu oraz wiedzy o kompilatorze, i.mi., jak kompilator tłumaczy instrukcje w języku programowania na instrukcje procesora?.

Wariant 2) wymaga dostępu do innych węzłów obliczeniowych, na przykład dedykowanych węzłów obliczeniowych, nieużywanych lub rzadziej używanych maszyn, maszyn wirtualnych z usług w chmurze, takich jak AWS, lub wynajmowanej mocy obliczeniowej z usług takich jak LoadTeam [5]. W rzeczywistości takie podejście jest wykorzystywane do tworzenia pakietów oprogramowania. Debian GNU/Linux używa tak zwanej sieci Autobuilder [17], a RedHat/Fedors używa Koji [18]. Google nazywa swój system BuildRabbit i doskonale to wyjaśnia w rozmowie Aysylu Greenberg [16]. distcc [2] to tak zwany rozproszony kompilator C, który umożliwia równoległe kompilowanie kodu na różnych węzłach i skonfigurowanie własnego systemu kompilacji.

Wariant 3 wykorzystuje równoległość na poziomie lokalnym. Może to być opcja o najlepszym stosunku kosztów do korzyści dla Ciebie, ponieważ nie wymaga dodatkowego sprzętu, jak w opcji 2. Warunkiem równoległego uruchomienia Make jest dodanie opcji -j w wywołaniu (skrót od -jobs). Określa liczbę zadań, które są uruchamiane w tym samym czasie. Poniższa lista prosi o uruchomienie 4 zadań równolegle:

Lista 2

$ make --jobs=4

Zgodnie z prawem Amdahla [23] skróci to czas budowy o prawie 50%. Należy pamiętać, że to podejście działa dobrze, jeśli pojedyncze cele nie są od siebie zależne; na przykład wynik celu 5 nie jest wymagany do zbudowania celu 3.

Jest jednak jeden efekt uboczny: wyjście komunikatów o stanie dla każdego celu Make wydaje się arbitralne i nie można ich już wyraźnie przypisać do celu. Kolejność wyjściowa zależy od aktualnej kolejności wykonania zadania.

Zdefiniuj wykonanie zlecenia wykonania

Czy istnieją stwierdzenia, które pomagają Make zrozumieć, które cele są od siebie zależne?? tak! Przykładowy Makefile z Listingu 3 mówi tak:

* aby zbudować cel „wszystkie”, uruchom instrukcje dla e1, e2 i e3

* cel e2 wymaga wcześniejszego zbudowania celu e3

Oznacza to, że cele e1 i e3 mogą być budowane równolegle, najpierw, następnie e2 następuje, gdy tylko budowa e3 zostanie zakończona, w końcu.

Lista 3

wszystkie: e1 e2 e3
e1:
dotknij jednego
e2: e3
dotknij dwa
e3:
dotknij trzy
czysty:
rm jeden dwa trzy

Wizualizuj tworzenie zależności

Sprytne narzędzie make2graph z projektu makefile2graph [19] wizualizuje zależności Make jako ukierunkowany graf acykliczny. Pomaga to zrozumieć, w jaki sposób różne cele są od siebie zależne. Make2graph wyświetla opisy wykresów w formacie kropki, które można przekształcić w obraz PNG za pomocą polecenia kropki z projektu Graphviz [22]. Wezwanie wygląda następująco:

Lista 4

$ zrób wszystko -Bnd | make2graph | kropka -Tpng -o wykres.png

Po pierwsze, Make jest wywoływany z celem „all”, a następnie opcjami „-B”, aby bezwarunkowo zbudować wszystkie cele, „-n” (skrót od „-dry-run”), aby udawać uruchamianie instrukcji dla celu, i „ -d” („-debug”), aby wyświetlić informacje debugowania. Dane wyjściowe są przesyłane do programu make2graph, który przesyła dane wyjściowe do kropki, która generuje wykres pliku obrazu.png w formacie PNG.


Wykres zależności kompilacji dla listingu 3

Więcej kompilatorów i systemów budowania

Jak już wyjaśniono powyżej, Make został opracowany ponad cztery dekady temu. Z biegiem lat, równoległe wykonywanie zadań stawało się coraz ważniejsze, a od tego czasu wzrosła liczba specjalnie zaprojektowanych kompilatorów i systemów budujących, aby osiągnąć wyższy poziom zrównoleglania. Lista narzędzi obejmuje:

Większość z nich została zaprojektowana z myślą o zrównoleglaniu i oferuje lepsze wyniki pod względem czasu budowy niż Make.

Wniosek

Jak widzieliście, warto pomyśleć o równoległych kompilacjach, ponieważ znacznie skraca to czas budowania do pewnego poziomu. Jednak nie jest to łatwe do osiągnięcia i wiąże się z pewnymi pułapkami [3]. Zaleca się przeanalizowanie zarówno kodu, jak i jego ścieżki budowania przed przejściem do równoległych kompilacji.

Linki i referencje

Gry OpenTTD vs Simutrans
OpenTTD vs Simutrans
Creating your own transport simulation can be fun, relaxing and extremely enticing. That's why you need to make sure that you try out as many games as...
Gry OpenTTD Tutorial
OpenTTD Tutorial
OpenTTD is one of the most popular business simulation games out there. In this game, you need to create a wonderful transportation business. However,...
Gry SuperTuxKart for Linux
SuperTuxKart for Linux
SuperTuxKart is a great title designed to bring you the Mario Kart experience free of charge on your Linux system. It is pretty challenging and fun to...