为多核机器自动设置作业(-j)标志?

发布于 2024-10-14 08:34:11 字数 168 浏览 9 评论 0原文

我在一台有大量核心的机器上有一个 Makefile,但在编译我的项目时我似乎总是忘记编写 -jX 并且它花费的时间比应有的时间长得多。

有什么方法可以通过环境变量或其他一些持久配置文件设置 -j 标志,以便 make 将在这台机器上自动并行执行多个作业?

I have a Makefile on a machine that has a ton of cores in it, but I always seem to forget to write -jX when compiling my project and it takes way longer than it should.

Is there some way I can set the -j flag through an environment variable or some other persistent config file so that make will automatically execute multiple jobs in parallel on this machine?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

枕花眠 2024-10-21 08:34:12

我假设你使用的是 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 也不是一个很好的解决方案,因为我经常从子目录构建并希望并行构建它们。但是,如果您有一个相当平坦的源层次结构,那么它可能适合您。

I'm assuming you're using Linux. This is from my ~/.bashrc

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

sample usage

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

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

To answer your specific question about putting this into a Makefile, I don't find it practical to sprinkle this logic all over my Makefiles. Putting this into a top level Makefile also isn't a great solution since I often build from sub-directories and wish to build them in parallel as well. However, if you have a fairly flat source hierarchy, it may work for you.

流年里的时光 2024-10-21 08:34:12

看起来 MAKEFLAGS 环境变量可以传递作为每个 make 运行的一部分的标志(至少对于 GNU make 来说)。我自己在这方面运气不佳,但可以使用 -l 而不是 -j 自动运行适合数量的作业您可用的核心数。

It appears that the MAKEFLAGS environment variable can pass flags that are part of every make run (at least for GNU make). I haven't had much luck with this myself, but it might be possible to use -l rather than -j to automatically run as many jobs as are appropriate for the number of cores you have available.

情归归情 2024-10-21 08:34:12

正如 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

As Jeremiah Willcock said, use MAKEFLAGS, but here is how to do it:

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

or you could just set a fixed value like this:

export MAKEFLAGS="-j 8"

If you really want to boost performance you should use ccache by adding something like the following to your Makefile:

CCACHE_EXISTS := $(shell ccache -V)
ifdef CCACHE_EXISTS
    CC := ccache $(CC)
    CXX := ccache $(CXX)
endif
日裸衫吸 2024-10-21 08:34:12

我通常在 bash 脚本中按如下方式执行此操作:

make -j$(nproc)

I usually do this as follows in my bash scripts:

make -j$(nproc)
冬天旳寂寞 2024-10-21 08:34:12

您可以向 Makefile 中添加类似于以下内容的行:

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

然后在规则中添加 ${NUMJOBS} 行,或将其添加到另一个 Makefile var 中(例如 >MAKEFLAGS)。这将使用 NUMJOBS 环境变量(如果存在);如果没有,则自动使用 -j4。您可以根据自己的喜好对其进行调整或重命名。

(注意:就我个人而言,我更喜欢默认值为 -j1"",特别是如果它要分发给其他人,因为虽然我也有多个核心,我在许多不同的平台上进行编译,并且经常忘记禁用 -jX 设置。)

You can add a line to your Makefile similar to the following:

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

Then add a ${NUMJOBS} line in your rules, or add it into another Makefile var (like MAKEFLAGS). This will use the NUMJOBS envvar, if it exists; if it doesn't, automatically use -j4. You can tune or rename it to your taste.

(N.B.: Personally, I'd prefer the default to be -j1 or "", especially if it's going to be distributed to others, because although I have multiple cores also, I compile on many different platforms, and often forget to dis-able the -jX setting.)

单挑你×的.吻 2024-10-21 08:34:12

别名不会在脚本内扩展。最好创建一个单独的 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` "$@"

Aliases are not expanded inside scripts. It's better to create a separate make script and place it into one of the $PATH directories:

#!/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` "$@"
守护在此方 2024-10-21 08:34:12

直到 2016 年的某个时候,您可以将其放入 makefile 中:(经过 GNU make 测试)

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

(其中 NUM_PPROCS 是根据此处的许多其他答案之一计算或设置的)并且,嘭!您正在进行多进程构建。

鉴于这已经停止工作,我能想到的最好的办法就是 makefile 调用自身,但使用 -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

Until sometime in 2016, you could put this in your makefile: (GNU make tested)

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

(where NUM_PPROCS is calculated or set according to one of many of the other answers here) And, bam! you have multi-process building going on.

Given that this has stopped working, the best thing that I could come up with is this, where the makefile calls itself, but with -jX and -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
三生路 2024-10-21 08:34:12

在使用所有 CPU 核心的 Ubuntu 16.4 上:

export MAKEFLAGS='-j$(nproc)'

export MAKEFLAGS='-j 2'

On Ubuntu 16.4 using all CPU cores:

export MAKEFLAGS='-j$(nproc)'

or

export MAKEFLAGS='-j 2'
兮子 2024-10-21 08:34:12

在 Makefile 的开头:

MAKEFLAGS+="j"

任何版本的 GNU Make 都不会采用数字参数 4.2 之前。 4.2 之后你可以这样做

MAKEFLAGS+="j2"

对于 4.2 之前的版本,如果你碰巧有一些作业用完了内存,您可以使用 util-linux-ng 中的 flock 让它们一次只运行一个。例如,ImageMagick 中的 convert 实用程序将使用其在用于 根据 Google 的建议优化图像,因此没有必要让它并行运行。

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

设置较长的等待时间很重要,因为 make 仍会并行运行大部分命令。因此,等待时间必须与最深队列执行时间一样。如果您有八个核心,并且八个大图像需要一分钟来优化,则必须将等待时间设置为至少一分钟。

对于数百个核心和巨大的图像,上面设置的六百秒可能还不够。

At the beginning of a Makefile:

MAKEFLAGS+="j"

It won't take numeric arguments for any version of GNU Make before 4.2. After 4.2 you can do:

MAKEFLAGS+="j2"

For versions earlier than 4.2 if you happen to have some jobs running out of memory, you could make them run only one at a time with flock from util-linux-ng. For example, a convert utility from ImageMagick will use all resources it can get when used to optimize images according to Google's recommendations, so there's no point to have it run in parallel.

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

It is important to set a long wait time because make will still run most of these commands in parallel. Therefore, wait time must be as such as the deepest queue execution time. If you have eight cores, and eight large images take a minute to optimize, you must set the wait time to at least a minute.

With hundreds of cores and huge images, six hundred seconds set above might not be enough.

临风闻羌笛 2024-10-21 08:34:12

我只需放入

alias make='make -j'

~/.profile~/.bashrc 即可。

根据手册

如果“-j”选项后面没有任何看起来像整数的内容,则作业槽数没有限制。

I would just put

alias make='make -j'

in ~/.profile or ~/.bashrc.

According to the manual:

If there is nothing looking like an integer after the ‘-j’ option, there is no limit on the number of job slots.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文