GNU Make

Компіляція коду паралельно за допомогою Make

Компіляція коду паралельно за допомогою Make

Будь-кого, кого ви запитаєте, як правильно створювати програмне забезпечення, запропонує Make як одну з відповідей. У системах GNU / Linux GNU Make [1] - це версія оригінального Make з відкритим вихідним кодом, випущена більше 40 років тому - в 1976 році. Make працює за допомогою Makefile - структурованого звичайного текстового файлу з такою назвою, який найкраще можна описати як інструкцію з побудови процесу побудови програмного забезпечення. Makefile містить ряд міток (так звані цілі) та конкретні інструкції, необхідні для виконання кожної цілі.

Простіше кажучи, Make - це інструмент побудови. Це слідує рецепту завдань із Makefile. Це дозволяє повторювати кроки в автоматизованому режимі, а не вводити їх у терміналі (і, можливо, робити помилки під час набору тексту).

У лістингу 1 наведено приклад Makefile з двома цілями "e1" і "e2", а також двома спеціальними цілями "all" і "clean."Запуск" make e1 "виконує інструкції для цілі" e1 "і створює порожній файл. Запуск “make e2” робить те саме для цілі “e2” і створює два порожні файли. Виклик “зробити все” спочатку виконує інструкції для цілі e1 та e2 наступної. Щоб видалити раніше створені файли один і два, просто виконайте виклик “make clean."

Лістинг 1

всі: e1 e2
e1:
торкніться одного
e2:
торкніться двох
чистий:
rm один два

Запуск Make

Поширеним випадком є ​​те, що ви пишете свій файл Make, а потім просто запускаєте команду “make” або “make all” для створення програмного забезпечення та його компонентів. Всі цілі будуються в послідовному порядку і без будь-якого розпаралелювання. Загальний час побудови - це сума часу, необхідного для побудови кожної окремої цілі.

Цей підхід добре працює для невеликих проектів, але займає досить багато часу для середніх та великих проектів. Цей підхід вже не сучасний, оскільки більшість поточних процесорів оснащені більш ніж одним ядром і дозволяють виконувати більше одного процесу одночасно. З огляду на ці ідеї, ми розглядаємо, чи можна і як паралельно розпочати процес побудови. Метою є просто скоротити час збірки.

Зробити вдосконалення

У нас є кілька варіантів - 1) спростити код, 2) розподілити окремі завдання на різні обчислювальні вузли, побудувати там код і зібрати звідти результат, 3) побудувати код паралельно на одній машині та 4) поєднати варіанти 2 і 3.

Варіант 1) не завжди простий. Це вимагає волі проаналізувати час реалізації реалізованого алгоритму та знання про компілятор, тобто.e., як компілятор переводить інструкції мовою програмування в інструкції процесора.

Варіант 2) вимагає доступу до інших обчислювальних вузлів, наприклад, виділених обчислювальних вузлів, невикористаних або менш використовуваних машин, віртуальних машин із хмарних служб, таких як AWS, або орендованих обчислювальних потужностей у таких служб, як LoadTeam [5]. Насправді цей підхід використовується для побудови програмних пакетів. Debian GNU / Linux використовує так звану мережу Autobuilder [17], а RedHat / Fedors - Кодзі [18]. Google називає свою систему BuildRabbit, і це чудово пояснено в доповіді Айсилу Грінберга [16]. distcc [2] - це так званий розподілений компілятор C, який дозволяє паралельно компілювати код на різних вузлах та налаштовувати власну систему збірки.

Варіант 3 використовує розпаралелювання на місцевому рівні. Це може бути варіант з найкращим для вас співвідношенням витрат і вигод, оскільки для нього не потрібно додаткове обладнання, як у варіанті 2. Вимога запускати паралельно Make - це додавання опції -j у виклик (скорочення від -jobs). Це визначає кількість завдань, які виконуються одночасно. У наведеному нижче списку пропонується зробити паралельно 4 роботи:

Лістинг 2

$ make --jobs = 4

Відповідно до закону Амдала [23], це скоротить час збірки майже на 50%. Майте на увазі, що такий підхід добре працює, якщо окремі цілі не залежать одна від одної; наприклад, вихід цілі 5 не потрібен для побудови цілі 3.

Однак є один побічний ефект: вихід повідомлень стану для кожного Make target виглядає довільним, і вони більше не можуть бути чітко призначені цілі. Порядок виведення залежить від фактичного порядку виконання завдання.

Визначте Зробити наказ про виконання

Чи існують твердження, які допомагають зрозуміти, які цілі залежать одна від одної? Так! У прикладі Makefile в лістингу 3 сказано наступне:

* щоб побудувати цільове значення "всі", виконайте інструкції для e1, e2 та e3

* ціль e2 вимагає побудови цілі e3 раніше

Це означає, що цілі e1 та e3 можна будувати паралельно, спочатку, потім e2 слідує, як тільки побудова e3 завершується, нарешті.

Лістинг 3

всі: e1 e2 e3
e1:
торкніться одного
e2: e3
торкніться двох
e3:
торкніться трьох
чистий:
rm один два три

Візуалізуйте Виконання залежностей

Розумний інструмент make2graph із проекту makefile2graph [19] візуалізує створення залежностей як спрямований ациклічний графік. Це допомагає зрозуміти, як різні цілі залежать одна від одної. Make2graph виводить описи графіків у крапковому форматі, який ви можете перетворити у зображення PNG, використовуючи команду dot із проекту Graphviz [22]. Виклик такий:

Лістинг 4

$ make all -Bnd | make2graph | dot -Tpng -o графік.PNG

По-перше, викликається Make із ціллю “все”, за якою йдуть опції “-B” для безумовної побудови всіх цілей, “-n” (скорочення від “-dry-run”), щоб зробити вигляд, що виконує інструкції для цілі, і “ -d ”(“ -debug ”) для відображення інформації про налагодження. Вихідні дані направляються в трубу make2graph, яка передає вихідні дані у крапку, яка генерує графік файлу зображення.PNG у форматі PNG.


Графік залежності від побудови для списку 3

Більше компіляторів та систем побудови

Як вже пояснювалося вище, Make було розроблено більше чотирьох десятиліть тому. З роками паралельне виконання робочих місць набувало дедалі більшого значення, і з тих пір зросла кількість спеціально розроблених компіляторів та систем побудови для досягнення більш високого рівня розпаралелювання. Список інструментів включає такі:

Більшість із них розроблені з урахуванням розпаралелювання та пропонують кращий результат щодо часу збірки, ніж Make.

Висновок

Як ви вже переконалися, варто подумати про паралельні збірки, оскільки це значно скорочує час збірки до певного рівня. Однак досягти цього непросто, і це має певні підводні камені [3]. Перш ніж переходити до паралельних збірок, рекомендується проаналізувати як ваш код, так і шлях його збірки.

Посилання та посилання

Встановіть найновіший емулятор Dolphin для Gamecube & Wii на Linux
Емулятор Dolphin дозволяє грати у вибрані вами ігри Gamecube та Wii на персональних комп’ютерах Linux (ПК). Будучи вільно доступним і відкритим ігров...
Як використовувати GameConqueror Cheat Engine в Linux
Стаття висвітлює посібник із використання механізму читів GameConqueror в Linux. Багато користувачів, які грають у ігри в Windows, часто використовуют...
Кращі емулятори ігрової консолі для Linux
У цій статті буде перелічено популярне програмне забезпечення для емуляції ігрової консолі, доступне для Linux. Емуляція - це рівень сумісності програ...