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