Компиляция с помощью g++ с использованием нескольких ядер

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

Ответ 1

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

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

make -j 4

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

gcc -pipe

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

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

Ответ 2

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

make -j4

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

Если вы используете 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х.

Ответ 7

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

Ответ 8

Параллельный 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 использовать несколько ядер при связывании?

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

Проверено в Ubuntu 18.10.