web-dev-qa-db-ja.com

マルチコアマシンのジョブ(-j)フラグを自動的に設定しますか?

大量のコアを搭載したマシンにMakefileがありますが、プロジェクトをコンパイルするときに-jXを書くのを忘れるのが常で、必要以上に時間がかかります。

Makeがこのマシン上で複数のジョブを並行して自動的に実行するように、環境変数またはその他の永続的な構成ファイルを介して-jフラグを設定する方法はありますか?

57

MAKEFLAGS環境変数は、すべてのmake実行の一部であるフラグを渡すことができるようです(少なくともGNU makeの場合)。私はあまり持っていません自分でこれを試してみてください。ただし、-l のではなく -j使用可能なコアの数に適した数のジョブを自動的に実行します。

34

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に入れることは、サブディレクトリからビルドすることが多く、それらも並行してビルドしたいことが多いため、優れたソリューションではありません。ただし、ソース階層がかなりフラットな場合は、機能する場合があります。

37
Sam Miller

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
27
jcoffland

私は通常、bashスクリプトで次のようにこれを行います。

make -j$(nproc)
15
Bl00dh0und

次のような行をMakefileに追加できます。

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

次に、ルールに${NUMJOBS}行を追加するか、別のMakefile var(MAKEFLAGSなど)に追加します。 NUMJOBS envvarが存在する場合、これが使用されます。そうでない場合は、自動的に-j4を使用します。好みに合わせて調整したり、名前を変更したりできます。

(注:個人的には、デフォルトを-j1または""にしたいと思います。特に他の人に配布する場合は、複数のコアも持っていますが、さまざまなプラットフォームでコンパイルしているため、そして、-jX設定をdis-ableにすることを忘れがちです。

6

エイリアスはスクリプト内で展開されません 。別の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` "$@"
6
svlasov

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
2
golvok

すべてのCPUコアを使用するUbuntu 16.4の場合:

export MAKEFLAGS='-j$(nproc)'

または

export MAKEFLAGS='-j 2'
2
mwweb

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秒では不十分な場合があります。

1
sanmai