Як визначити максимальну кількість, яку потрібно передати опції make -j?


31

Я хочу скласти якомога швидше. Піди розберися. І хотілося б автоматизувати вибір номера, що слідує за -jопцією. Як я можу програмно вибрати це значення, наприклад, у сценарії оболонки?

Чи є вихідний nprocеквівалент кількості потоків, з якими я маю компілювати?

make -j1 make -j16

Відповіді:


34

nprocдає кількість наявних процесорних ядер / потоків, наприклад 8 на чотирьохядерному процесорі, що підтримує двосторонній SMT.

Кількість завдань, які можна виконувати паралельно з makeвикористанням -jопції, залежить від ряду факторів:

  • об'єм доступної пам'яті
  • об'єм пам'яті, використаний кожним makeзавданням
  • ступінь makeроботи, яка пов'язана з I / O або CPU

make -j$(nproc) це гідне місце для початку, але зазвичай ви можете використовувати більш високі значення, доки ви не вичерпаєте наявну пам'ять і не почнете молотити.

Для дійсно швидких збірок, якщо у вас є достатня кількість пам’яті, я рекомендую використовувати A tmpfs, таким чином більшість завдань буде пов'язана з процесором і make -j$(nproc)працюватиме якомога швидше.


3
і ccacheдля подальшого відновлення, але це OT
solsTiCe

1
Чи варто використовувати щось на зразок GNU паралельно тут?
terdon

Якщо я використовую a tmpfs, чи обмежуватимуся я розміром каталогу, який завжди менший за розмір фізичної оперативної пам’яті?
тарабайт

2
Це не велика відповідь, але в суворому дусі на питання програмного визначення найшвидшого значення "j" ви можете циклічити j від 1 до якоїсь розумної верхньої межі (2x nproc ??) і обернути make в timeдзвінок. Очистіть результати, повторіть промивання повтором - і закінчіть сортування значень часу / j.
Jeff Schaller

3
@terdon No. Make - це все, що стосується вирішення залежностей, а це означає, що завдання все одно потрібно виконувати в певному порядку. Паралельно з GNU це не хвилює. З іншого боку, вирішення того, які завдання безпечно виконувати паралельно, а які - не є важкою проблемою. Усі програми, які пропонували паралельні побудови, потребували років, поки вони не стали дещо корисними.
lcd047

6

На жаль, навіть різні частини однієї збірки можуть бути оптимальними при суперечливих значеннях j-коефіцієнта, залежно від того, що будується, як, який із системних ресурсів є вузьким місцем на той час, що ще відбувається на машині збирання, що відбувається в мережа (якщо використовується техніка розподіленої збірки), стан / розташування / продуктивність багатьох систем кешування, що беруть участь у складанні тощо.

Складання 100 крихітних файлів C може бути швидшим, ніж компіляція одного величезного файлу або навпаки. Створення невеликого високосмугового коду може бути повільніше, ніж створення величезної кількості прямого / лінійного коду.

Навіть контекст побудови має значення - використання aj-фактора, оптимізованого для побудови на спеціалізованих серверах, які точно налаштовані на ексклюзивні, неперекриваються збірки, можуть дати дуже неприємні результати при використанні розробниками, що будують паралельно на одному спільному сервері (кожна така збірка може зайняти більше час, ніж усі вони поєднуються, якщо вони серіалізовані) або на серверах з різною конфігурацією апаратних засобів або віртуалізованими.

Існує також аспект правильності специфікації збірки. Дуже складні побудови можуть мати умови перегонів, що спричиняють періодичні збої в збірці зі швидкістю виникнення, які можуть дико змінюватися зі збільшенням або зменшенням j-фактора.

Я можу продовжувати і продовжувати. Справа в тому, що ви повинні фактично оцінити свою збірку в самому контексті, для якого ви хочете оптимізувати j-фактор. @Jeff Schaller застосовується: повторіть, поки ви не знайдете найкращу форму. Особисто я б почав із значення nproc, спробуйте вгору спочатку та вниз, лише якщо спроби вгору показують негайну деградацію.

Можливо, буде гарною ідеєю спочатку виміряти кілька однакових складових у нібито однакових контекстах, просто щоб отримати уявлення про мінливість ваших вимірювань - якщо занадто висока, це може поставити під загрозу всі ваші зусилля з оптимізації (20-відсоткова змінність повністю затьмарить 10% покращення / деградаційне зчитування в пошуку j-фактора).

Нарешті, IMHO краще використовувати сервер (адаптивний) сервіс, якщо він підтримується і доступний замість фіксованого j-фактора - він стабільно забезпечує кращу ефективність збірки у широких межах.


добре сказано щодо залежностей основи побудови. Чи можете ви прокоментувати пропуск без параметра фіксованого номера за допомогою -jпараметра? напр.make -j
тарабайт

4
make -jпородить стільки робочих місць, скільки дозволяють залежності, як бомби вилки ( superuser.com/questions/927836/… ); збірка буде сканувати в кращому випадку витрачаючи більшість процесорів на управління процесами, ніж їх запуск ( superuser.com/questions/934685/… ), а в дуже паралельних побудовах у системи не вистачить пам’яті / swap або pid #s, і збірка не вдасться .
Дан Корнілеску

3

Найбільш прямолінійний спосіб - це nprocтак:

make -j`nproc`

Команда nprocповерне кількість ядер на вашій машині. Загорнувши його в галочки, nprocкоманда спочатку виконає, поверне число, і це число буде передано в make.

У вас може виникнути деякий анекдотичний досвід, коли виконання підрахунку ядра + 1 прискорює час компіляції. Це більше пов'язане з такими факторами, як затримка вводу-виводу, інші затримки ресурсів та інші наявні обмеження ресурсів.

Для цього nproc+1спробуйте:

make -j$((`nproc`+1))

0

Якщо ви хочете написати makeкоманду для використання стільки паралельних працівників, скільки у вас віртуальних процесорів, пропоную використовувати:

nproc | xargs -I % make -j%

Яка може бути записана як окрема команда, або як RUNдиректива всередині Dockerfile(оскільки Docker не підтримує вкладені команди)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.