Définition automatique du drapeau jobs (- j) pour une machine multicore?

j'ai un Makefile sur une machine qui a une tonne de noyaux dedans, mais je semble toujours oublier d'écrire -jX lors de la compilation de mon projet et il prend beaucoup plus de temps qu'il ne devrait.

y a-t-il un moyen pour que je puisse mettre le drapeau -j à travers une variable d'environnement ou un autre fichier de configuration persistant de sorte que make exécutera automatiquement plusieurs tâches en parallèle sur cette machine?

55
demandé sur Flimzy 2011-01-24 06:38:21

10 réponses

il apparaît que la variable d'environnement MAKEFLAGS peut passer les drapeaux qui font partie de chaque make lancé (au moins pour GNU make). Je n'ai pas eu beaucoup de chance avec moi-même, mais il pourrait être possible d'utiliser des -l plutôt que -j pour exécuter automatiquement autant d'emplois que sont appropriés pour le nombre de cœurs disponibles.

32
répondu Jeremiah Willcock 2011-01-24 03:44:31

je suppose que vous utilisez Linux. C'est de mon ~/.bashrc

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

exemple d'utilisation

samm@host src> echo $NUMCPUS
8
samm@host src> pmake

devient time nice make -j8 --load-average=8 .

pour répondre à votre question spécifique sur la mise en place d'un Makefile , Je ne trouve pas pratique de saupoudrer cette logique sur mes Makefiles. Mettre ceci dans un Makefile de haut niveau n'est pas non plus une bonne solution puisque je construis souvent à partir de sous-répertoires et que je souhaite construire en parallèle ainsi. Cependant, si vous avez une hiérarchie des sources assez uniforme, cela peut fonctionner pour vous.

34
répondu Sam Miller 2011-01-24 03:54:45

comme Jérémie Willcock a dit, utilisez MAKEFLAGS , Mais voici comment faire:

export MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)"

ou vous pouvez définir une valeur fixe comme ceci:

export MAKEFLAGS="-j 8"

si vous voulez vraiment augmenter la performance, vous devez utiliser ccache en ajoutant quelque chose comme ce qui suit à votre Makefile :

CCACHE_EXISTS := $(shell ccache -V)
ifdef CCACHE_EXISTS
    CC := ccache $(CC)
    CXX := ccache $(CXX)
endif
25
répondu jcoffland 2015-10-21 20:27:06

je fais habituellement ceci comme suit dans mes scripts bash:

make -j$(nproc)
10
répondu Bl00dh0und 2016-12-20 16:41:25

vous pouvez ajouter une ligne à votre Makefile similaire à la suivante:

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

puis Ajouter une ligne ${NUMJOBS} dans vos règles, ou l'ajouter dans un autre Makefile var (comme MAKEFLAGS ). Ceci utilisera le NUMJOBS envvar, s'il existe; s'il n'existe pas, utilisez automatiquement -j4 . Vous pouvez l'accorder ou le renommer à votre goût.

(N.B.: personnellement, je préférerais que la valeur par défaut soit -j1 ou "" , surtout si elle va pour être distribué à d'autres, parce que même si j'ai plusieurs noyaux aussi, je compile sur de nombreuses plateformes différentes, et oublie souvent de dis -capable le réglage -jX .)

6
répondu Sdaz MacSkibbons 2011-01-24 03:44:40

les alias ne sont pas développés dans les scripts . Il est préférable de créer un script séparé make et de le placer dans l'un des répertoires $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
répondu svlasov 2017-04-13 12:36:27

sur Ubuntu 16.4 en utilisant tous les cœurs CPU:

export MAKEFLAGS='-j$(nproc)'

ou

export MAKEFLAGS='-j 2'
2
répondu mwweb 2017-09-08 13:39:43

Jusqu'à l'année dernière, vous pouviez le faire dans votre makefile: (GNU make tested)

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

(où NUM_PPROCS est calculé ou ensemble selon l'une des nombreuses autres réponses ici) Et, bam! vous avez la construction multi-processus en cours.

étant donné que cela a cessé de fonctionner, la meilleure chose que j'ai pu trouver est celle-ci, où le makefile s'appelle lui-même, mais avec -jX et -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
1
répondu golvok 2017-06-10 21:53:11

au début d'un Makefile:

MAKEFLAGS+="j"

il ne prendra pas d'arguments numériques pour toute version de GNU Make Avant 4.2 .

s'il vous arrive d'avoir des jobs qui manquent de mémoire, vous pouvez les faire exécuter un seul à la fois avec flock de util-linux-ng. Par exemple, un utilitaire convert d'ImageMagick utilisera toutes les ressources qu'il peut obtenir lorsqu'il est utilisé pour optimiser les images selon Recommandations de Google , il n'y a donc pas de raison de le faire fonctionner en parallèle.

%.min.jpg: %.jpg
    @flock --wait 600 Makefile convert $< -sampling-factor 4:2:0 -strip $@

il est important de définir un long temps d'attente car make exécutera encore la plupart de ces commandes en parallèle. Par conséquent, les temps d'attente doit être comme le plus profond de la file d'attente temps d'exécution. Si vous avez huit cœurs, et huit grandes images prennent une minute pour optimiser, vous devez régler le temps d'attente à au moins une minute.

Avec des centaines de cœurs et d'énormes images, six cents secondes fixé ci-dessus pourrait ne pas être suffisant.

1
répondu sanmai 2018-02-08 06:16:31

je voudrais juste mettre

alias make='make -j'

dans ~/.profile ou ~/.bashrc .

selon le manuel :

S'il n'y a rien qui ressemble à un entier après l'option ‘-j’, il n'y a pas de limite sur le nombre de fentes d'emploi.

-1
répondu Alberto 2013-06-05 14:57:40