Компиляция с g ++ с использованием нескольких ядер - PullRequest
160 голосов
/ 06 января 2009

Быстрый вопрос: что означает флаг компилятора, позволяющий g ++ порождать несколько своих экземпляров для более быстрой компиляции больших проектов (например, 4 исходных файла за один раз для многоядерного процессора)?

Большое спасибо.

Ответы [ 8 ]

223 голосов
/ 06 января 2009

Вы можете сделать это с помощью make - с помощью gnu make это флаг -j (это также поможет на однопроцессорной машине).

Например, если вы хотите 4 параллельных задания из make:

make -j 4

Вы также можете запустить gcc в трубе с

gcc -pipe

Это передаст этапы компиляции, что также поможет поддерживать занятость ядер.

Если у вас также есть дополнительные машины, вы можете проверить distcc , который также будет обрабатывать компиляции для них.

39 голосов
/ 06 января 2009

Нет такого флага, и если он работает против философии Unix, согласно которой каждый инструмент должен выполнять только одну функцию и выполнять ее хорошо. Порождение процессов компилятора концептуально является задачей системы сборки. Вероятно, вы ищете флаг -j (jobs) для GNU make, например

make -j4

Или вы можете использовать pmake или аналогичные системы параллельного создания.

11 голосов
/ 06 января 2009

Люди упоминали make, но bjam также поддерживает аналогичную концепцию. Использование bjam -jx указывает bjam на создание до x одновременных команд.

Мы используем одни и те же сценарии сборки в Windows и Linux, и использование этой опции вдвое сокращает время сборки на обеих платформах. Ницца.

8 голосов
/ 06 января 2009

make сделает это за вас. Исследуйте переключатели -j и -l на странице руководства. Я не думаю, что g++ можно распараллелить.

5 голосов
/ 21 августа 2011

distcc также можно использовать для распространения компиляций не только на текущем компьютере, но и на других компьютерах в ферме, на которых установлен distcc.

3 голосов
/ 30 мая 2018

Если вы используете make, введите -j. От man make:

  -j [jobs], --jobs[=jobs]
       Specifies the number of jobs (commands) to run simultaneously.  
       If there is more than one -j option, the last one is effective.
       If the -j option is given without an argument, make will not limit the
       number of jobs that can run simultaneously.

И, что особенно важно, если вы хотите написать сценарий или определить количество доступных ядер (в зависимости от вашей среды, и если вы работаете во многих средах, это может сильно измениться), вы можете использовать вездесущую функцию Python cpu_count() :

https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count

Как это:

make -j $(python3 -c 'import multiprocessing as mp; print(int(mp.cpu_count() * 1.5))')

Если вы спросите, почему 1.5 я процитирую пользователя artless-noise в комментарии выше:

Число 1,5 из-за отмеченной проблемы с вводом / выводом. Это эмпирическое правило. Около 1/3 заданий будет ожидать ввода-вывода, поэтому остальные задания будут использовать доступные ядра. Число, превышающее число ядер, лучше, и вы можете даже подняться до 2х.

2 голосов
/ 06 января 2009

Я не уверен насчет g ++, но если вы используете GNU Make, то "make -j N" (где N - количество потоков, которые может создать make) позволит make запускать несколько заданий g ++ одновременно (пока файлы не зависят друг от друга).

1 голос

GNU параллельно

Я делал синтетический тест для компиляции и не мог потрудиться написать Makefile, поэтому я использовал:

sudo apt-get install parallel
ls | grep -E '\.c$' | parallel -t --will-cite "gcc -c -o '{.}.o' '{}'"

Пояснение:

  • {.} принимает входной аргумент и удаляет его расширение
  • -t распечатывает команды, которые запускаются, чтобы дать нам представление о прогрессе
  • --will-cite удаляет запрос на цитирование программного обеспечения, если вы публикуете результаты, используя его ...

parallel настолько удобно, что я даже сам могу проверить метку времени:

ls | grep -E '\.c$' | parallel -t --will-cite "\
  if ! [ -f '{.}.o' ] || [ '{}' -nt '{.}.o' ]; then
    gcc -c -o '{.}.o' '{}'
  fi
"

xargs -P также может запускать задания параллельно, но немного менее удобно выполнять с ним расширение или запускать несколько команд: Вызов нескольких команд через xargs

Параллельное связывание было задано по адресу: Может ли gcc использовать несколько ядер при связывании?

TODO: Мне кажется, я где-то читал, что компиляция может быть сведена к умножению матриц, поэтому, возможно, можно также ускорить компиляцию одного файла для больших файлов. Но я не могу найти ссылку сейчас.

Протестировано в Ubuntu 18.10.

...