大量のコアを搭載したマシンにMakefileがありますが、プロジェクトをコンパイルするときに-jX
を書くのを忘れるのが常で、必要以上に時間がかかります。
Makeがこのマシン上で複数のジョブを並行して自動的に実行するように、環境変数またはその他の永続的な構成ファイルを介して-j
フラグを設定する方法はありますか?
MAKEFLAGS
環境変数は、すべてのmake
実行の一部であるフラグを渡すことができるようです(少なくとも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
に入れることに関する特定の質問に答えるために、Makefile全体にこのロジックを振りかけることは実用的ではありません。これをトップレベルのMakefileに入れることは、サブディレクトリからビルドすることが多く、それらも並行してビルドしたいことが多いため、優れたソリューションではありません。ただし、ソース階層がかなりフラットな場合は、機能する場合があります。
Jeremiah Willcockが言ったように、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
私は通常、bashスクリプトで次のようにこれを行います。
make -j$(nproc)
次のような行をMakefileに追加できます。
NUMJOBS=${NUMJOBS:-" -j4 "}
次に、ルールに${NUMJOBS}
行を追加するか、別のMakefile
var(MAKEFLAGS
など)に追加します。 NUMJOBS envvarが存在する場合、これが使用されます。そうでない場合は、自動的に-j4
を使用します。好みに合わせて調整したり、名前を変更したりできます。
(注:個人的には、デフォルトを-j1
または""
にしたいと思います。特に他の人に配布する場合は、複数のコアも持っていますが、さまざまなプラットフォームでコンパイルしているため、そして、-jX
設定をdis-ableにすることを忘れがちです。
エイリアスはスクリプト内で展開されません 。別の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` "$@"
2016年のいつかまで、これをmakefileに入れることができました:(GNU makeテスト済み)
MAKEFLAGS += "-j$(NUM_CORES) -l$(NUM_CORES)
(どこ NUM_PPROCS
は、他の多くの回答の1つに従って計算または設定されます)そして、bam!マルチプロセスビルディングが進行中です。
これが機能しなくなったことを考えると、私が思いつくことができる最高のものは、メイクファイルがそれ自体を呼び出すが、-jX
および-lX
。
ifeq ($(PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB),done)
all: ...
...
other_target: ...
...
else
# add parallelism equal to number of cores every time.
# "random" strings are to ensure uniqueness
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
endif
すべてのCPUコアを使用するUbuntu 16.4の場合:
export MAKEFLAGS='-j$(nproc)'
または
export MAKEFLAGS='-j 2'
Makefileの先頭:
MAKEFLAGS+="j"
GNU Make 4.2より前 。4.2より後 できます :
MAKEFLAGS+="j2"
4.2より前のバージョンでは、メモリ不足のジョブがある場合、util-linux-ngのflock
を使用して、一度に1つのジョブのみを実行できます。たとえば、ImageMagickのconvert
ユーティリティは、 Googleの推奨に従って画像を最適化する に使用すると取得できるすべてのリソースを使用するため、並行して実行する意味はありません。
%.min.jpg: %.jpg
@flock --wait 600 Makefile convert $< -sampling-factor 4:2:0 -strip $@
Makeはこれらのコマンドのほとんどを並行して実行するため、長い待機時間を設定することが重要です。したがって、待機時間は、最も深いキュー実行時間などである必要があります。 8つのコアがあり、8つの大きなイメージの最適化に1分かかる場合、待機時間を少なくとも1分に設定する必要があります。
数百のコアと巨大な画像では、上記の600秒では不十分な場合があります。