Ответы:
nproc
дает число доступных ядер / потоков ЦП, например, 8 на четырехъядерном ЦП, поддерживающем двустороннюю SMT.
Количество заданий, которые вы можете выполнять параллельно с make
использованием этой -j
опции, зависит от ряда факторов:
make
работойmake
задания связаны с вводом / выводом или с процессоромmake -j$(nproc)
это хорошее место для начала, но вы можете использовать более высокие значения, если вы не исчерпаете доступную память и не начнете перебивать.
Для действительно быстрых сборок, если у вас достаточно памяти, я рекомендую использовать так tmpfs
, чтобы большинство заданий было связано с процессором и make -j$(nproc)
работало как можно быстрее.
tmpfs
, буду ли я ограничен размером каталога, который всегда меньше моего физического объема ОЗУ?
time
вызов. Очистите результаты, снова промойте и промойте значения time / j.
К сожалению, даже разные части одной и той же сборки могут быть оптимальными с конфликтующими значениями j-фактора, в зависимости от того, что собирается, каким образом, какие системные ресурсы являются узким местом в то время, что еще происходит на машине сборки, что происходит в сеть (если используются методы распределенной сборки), состояние / местоположение / производительность многих систем кэширования, участвующих в сборке, и т. д.
Компиляция 100 крошечных C-файлов может быть быстрее, чем компиляция одного огромного или наоборот. Построение небольшого очень сложного кода может быть медленнее, чем создание огромного количества прямого / линейного кода.
Имеет значение даже контекст сборки - использование aj-фактора, оптимизированного для сборок на выделенных серверах, точно настроенных для эксклюзивных неперекрывающихся сборок, может привести к очень разочаровывающим результатам, когда разработчики используют параллельную сборку на одном общем сервере (каждая такая сборка может занять больше времени, чем все они вместе взятые, если сериализованы) или на серверах с различными аппаратными конфигурациями или виртуализированы.
Есть также аспект правильности спецификации сборки. Очень сложные сборки могут иметь условия гонки, вызывающие периодические сбои сборки с частотой появления, которая может сильно варьироваться с увеличением или уменьшением j-фактора.
Я могу продолжать и продолжать. Дело в том, что вы должны реально оценить свою сборку в том же контексте, для которого вы хотите оптимизировать j-фактор. Комментарий @Джеффа Шаллера применим: итерируйте, пока не найдете свое лучшее соответствие. Лично я бы начал со значения nproc, попробуйте сначала вверх и вниз, только если попытки вверх показывают немедленную деградацию.
Может быть хорошей идеей будет сначала измерить несколько идентичных сборок в предположительно идентичных контекстах, просто чтобы получить представление об изменчивости ваших измерений - если слишком высокое, это может поставить под угрозу все ваши усилия по оптимизации (20% -ая изменчивость полностью затмевает улучшение на 10% / ухудшение чтения в поиске j-фактора).
И наконец, IMHO, лучше использовать (адаптивный) сервер заданий, если он поддерживается и доступен, вместо фиксированного j-фактора - он последовательно обеспечивает лучшую производительность сборки в более широком диапазоне контекстов.
-j
параметром? напр.make -j
make -j
будет порождать столько заданий, сколько позволяют зависимости, как бомба-вилка ( superuser.com/questions/927836/… ); сборка будет в лучшем случае сканировать, тратя больше ресурсов ЦП на управление процессами, чем на их запуск ( superuser.com/questions/934685/… ), а в высокопараллельных сборках системе не хватит памяти / swap или pid #, и сборка завершится неудачно ,
Самый простой способ - использовать nproc
так:
make -j`nproc`
Команда nproc
вернет количество ядер на вашем компьютере. Обернув его в галочки, nproc
команда выполнится первой, вернет число, и это число будет передано make
.
У вас может быть некоторый анекдотичный опыт, когда выполнение core-count + 1 приводит к более быстрому времени компиляции. Это в большей степени связано с такими факторами, как задержки ввода-вывода, другие задержки ресурсов и другая доступность ограничений ресурсов.
Чтобы сделать это nproc+1
, попробуйте это:
make -j$((`nproc`+1))
Если вы хотите написать make
команду, чтобы использовать столько параллельных рабочих, сколько у вас виртуальных процессоров, я предлагаю использовать:
nproc | xargs -I % make -j%
Который может быть записан как отдельная команда или как RUN
директива внутри Dockerfile
(так как Docker не поддерживает вложенные команды)
ccache
для дальнейшего восстановления, но это ОТ