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

StackOverflow https://stackoverflow.com/questions/414714

Вопрос

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

Это было полезно?

Решение

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

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

make -j 4

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

gcc -pipe

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

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

Другие советы

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

make -j4

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

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

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

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

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

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

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

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top