Подтвердить что ты не робот

Автоматическая установка заданий (-j) для многоядерной машины?

У меня есть Makefile на машине, в которой есть тонны ядер, но я всегда забываю писать -jX при компиляции моего проекта, и это занимает больше времени, чем нужно.

Можно ли установить флаг -j через переменную среды или какой-либо другой файл постоянной конфигурации, чтобы make автоматически выполнял несколько заданий параллельно на этой машине?

4b9b3361

Ответ 1

Кажется, что переменная среды MAKEFLAGS может передавать флаги, которые являются частью каждого запуска make (по крайней мере, для GNU make). Мне не повезло с этим самим, но вместо -j можно было бы использовать -l, чтобы автоматически запускать столько заданий, сколько подходит для количества доступных вам ядер.

Ответ 2

Я предполагаю, что вы используете Linux. Это от моего ~/.bashrc

# parallel make
export NUMCPUS=`grep -c '^processor' /proc/cpuinfo`
alias pmake='time nice make -j$NUMCPUS --load-average=$NUMCPUS'

использование образца

[email protected] src> echo $NUMCPUS
8
[email protected] src> pmake

становится time nice make -j8 --load-average=8.

Чтобы ответить на ваш конкретный вопрос о том, чтобы поместить это в Makefile, я не считаю целесообразным посыпать эту логику во всех своих файлах Makefile. Включение этого в верхний уровень Makefile также не является отличным решением, поскольку я часто создаю его из подкаталогов и хочу строить их параллельно. Однако, если у вас довольно ровная иерархия источников, она может работать для вас.

Ответ 3

Как сказал Иеремия Уилкок, используйте 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

Ответ 4

Я обычно делаю это следующим образом в моих сценариях bash:

make -j$(nproc)

Ответ 5

Вы можете добавить строку в свой файл Makefile, как показано ниже:

NUMJOBS=${NUMJOBS:-" -j4 "}

Затем добавьте строку ${NUMJOBS} в свои правила или добавьте ее в другую Makefile var (например, MAKEFLAGS). Это будет использовать NUMJOBS envvar, если он существует; если это не так, автоматически используйте -j4. Вы можете настроить или переименовать его по своему вкусу.

(NB: Лично я предпочел бы, чтобы по умолчанию было -j1 или "", особенно если оно будет распространено среди других, потому что, хотя у меня есть несколько ядер, я компилирую на разных платформах и часто забывайте отключить настройку -jX.)

Ответ 7

До тех пор, пока в прошлом году вы не смогли сделать это в своем make файле: (GNU make test)

MAKEFLAGS += "-j$(NUM_CORES) -l$(NUM_CORES)

(где NUM_PPROCS вычисляется или задается в соответствии с одним из многих других ответов здесь) И, bam! у вас многоэтапное строительство.

Учитывая, что это перестало работать, самое лучшее, что я мог придумать, это то, где 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) [email protected] 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

Ответ 8

В Ubuntu 16.4 с использованием всех ядер процессора:

export MAKEFLAGS='-j$(nproc)'

или

export MAKEFLAGS='-j 2'

Ответ 9

В начале файла 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 [email protected]

Важно установить длительное время ожидания, так как make все равно будет выполнять большинство этих команд параллельно. Поэтому время ожидания должно быть таким, как самое глубокое время выполнения очереди. Если у вас восемь ядер и восемь больших изображений занимают минуту, чтобы оптимизировать, вы должны установить время ожидания как минимум на минуту.

С сотнями ядер и огромными изображениями, установленных на шестьсот секунд, может быть недостаточно.

Ответ 10

Я бы просто положил

alias make='make -j'

в ~/.profile или ~/.bashrc.

В соответствии с manual:

Если после опции "-j нет ничего похожего на целое число, количество вакансий не ограничено.