Автоматическая установка флага задания (- j) для многоядерной машины?
У меня есть Makefile на машине, которая имеет тонну ядер в нем, но я всегда, кажется, забываю писать -jX при компиляции моего проекта и это занимает гораздо больше времени, чем это должно быть.
есть ли способ я могу установить -j флаг через переменную окружения или какой-либо другой постоянный файл конфигурации, чтобы make автоматически выполнял несколько заданий параллельно на этой машине?
10 ответов:
получается, что
MAKEFLAGSпеременная окружения может передавать флаги, которые являются частью каждогоmakerun (по крайней мере, для GNU make). Мне самому не очень повезло с этим, но можно было бы использовать-l, а не-jавтоматически запускать столько заданий, сколько соответствует количеству доступных ядер.
Я предполагаю, что вы используете Linux. Это от моего
~/.bashrc# parallel make export NUMCPUS=`grep -c '^processor' /proc/cpuinfo` alias pmake='time nice make -j$NUMCPUS --load-average=$NUMCPUS'пример использования
samm@host src> echo $NUMCPUS 8 samm@host src> pmakeстановится
time nice make -j8 --load-average=8.чтобы ответить на ваш конкретный вопрос о сдачи его в
Makefile, Я не считаю практичным разбрызгивать эту логику по всем моим Makefiles. Помещение этого в Makefile верхнего уровня также не является отличным решением, так как я часто строю из подкаталогов и хочу строить их параллельно. Однако, если у вас есть довольно плоский исходная иерархия, она может работать для вас.
как сказал Иеремия Уиллкок, используйте
MAKEFLAGS, но вот как это сделать:export MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)"или вы можете просто установить фиксированное значение, как это:
export MAKEFLAGS="-j 8"если вы действительно хотите, чтобы повысить производительность, вы должны использовать
ccacheдобавлять что-то вроде следующего в вашMakefile:CCACHE_EXISTS := $(shell ccache -V) ifdef CCACHE_EXISTS CC := ccache $(CC) CXX := ccache $(CXX) endif
вы можете добавить строку в свой Makefile, похожую на следующую:
NUMJOBS=${NUMJOBS:-" -j4 "}добавить
${NUMJOBS}строка в ваших правилах, или добавить его в другойMakefilevar (напримерMAKEFLAGS). Это будет использовать NUMJOBS envvar, если он существует; если это не так, автоматически использовать-j4. Вы можете настроить или переименовать его на свой вкус.(N. B.: лично я бы предпочел, чтобы по умолчанию было
-j1или"", особенно если он будет распространен среди других, потому что хотя у меня есть несколько ядер также, я компилирую на разных платформах, и часто забываю СОП-возможность-jXнастройка.)
псевдонимы не раскрываются внутри скриптов. Лучше создать отдельный
makeскрипт и поместите его в один из$PATHкаталоги:#!/bin/sh if [ -f /proc/cpuinfo ]; then CPUS=`grep processor /proc/cpuinfo | wc -l` else CPUS=1 fi /usr/bin/make -j`expr $CPUS + 1` "$@"
на Ubuntu 16.4 с использованием всех ядер процессора:
export MAKEFLAGS='-j$(nproc)'или
export MAKEFLAGS='-j 2'
пока где-то в прошлом году вы не могли сделать это в своем makefile: (GNU make tested)
MAKEFLAGS += "-j$(NUM_CORES) -l$(NUM_CORES)(где
NUM_PPROCSрассчитывается или устанавливается в соответствии с одним из многих других ответов здесь) и, бац! у вас есть многопроцессное здание происходит.учитывая, что это перестало работать, лучшее, что я мог придумать, это то, где makefile называет себя, но с
-jXи-lX.# add parallelism equal to number of cores every time. # it seems that adding -jX to MAKEFLAGS directly doesn't work any more. # included some "random" strings to ensure uniqueness ifneq ($(PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB),done) NUM_CORES ?= $(shell grep -c "vendor_id" /proc/cpuinfo) MAKEFLAGS +=" -j$(NUM_CORES) -l$(NUM_CORES) " # for the default target case parallel_wrapper_default_target_anthsqjkshbeohcbmeuthnoethoaeou: $(MAKE) PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB=done # catches everything else % : $(MAKE) $@ PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB=done # the match for this else is at the end of the file else ##### rest of makefile here ##### all: ... ... other_target: ... ... ##### etc. ##### endif
В начале файла Makefile:
MAKEFLAGS+="j"он не будет принимать числовые аргументы для любой версии GNU Make до 4.2.
если у вас есть некоторые задания, работающие из памяти, вы можете заставить их работать только по одному за раз с
flockиз util-linux-ng. Например,convertутилиты из пакета ImageMagick будет использовать все ресурсы, которые он может получить при использовании оптимизация изображений в соответствии с рекомендациями Google, так что нет смысла пусть он работает параллельно.%.min.jpg: %.jpg @flock --wait 600 Makefile convert $< -sampling-factor 4:2:0 -strip $@важно установить долгое время ожидания, потому что make все равно будет выполнять большинство этих команд параллельно. Поэтому время ожидания должно быть таким же, как самое глубокое время выполнения очереди. Если у вас есть восемь ядер и восемь больших изображений занимают минуту для оптимизации, вы должны установить время ожидания не менее минуты.
С сотнями ядер и огромными изображениями, шестьсот секунд, установленных выше, может быть недостаточно.
Я бы просто поставил
alias make='make -j'на
~/.profileили~/.bashrc.По словам руководство:
Если после опции '- j ' нет ничего похожего на целое число, то количество слотов заданий не ограничено.
Comments