这是在GNU 3.82,RHEL 7上运行的。即使我在--jobs中通过了,Make似乎也是按顺序运行的。
我正在做大约700 K的琐碎工作--将大型gzip文件连接到其他gzip文件上。如果只有一个文件要连接,那么我将创建一个符号链接。以下是命令:
# Pattern to rebuild gzip file - concatenate if needed, otherwise just link
$(THISDIR)/%.tgz:
mkdir -p $$(dirname $@) && \
if [ $$(echo '$^' | wc -w) -gt 1 ]; then cat $^ > $@; else ln -s $^ $@; fi为了避免另一次shell调用,我已经被&&隔开了,没有什么区别。
在700000个就业岗位中,约有60万人只是在创造象征性的联系。对于其余部分,要连接的文件的平均数量为4个。
为什么这么慢?我得到了5-8 TPS。更重要的是,即使我指定了(在有64个CPUS的计算机上):
make --jobs --max-load=48我在top上看到的进程很少。因此,看来Make根本不运行并行作业。在GNU Make上,并行性是否有一个最小的作业长度来有效工作?
top现在的平均负载是
top - 22:50:32 up 3 days, 13:13, 32 users, load average: 7.96, 7.44, 5.73以下是一些可能有帮助的进一步细节:
$^.$@中都没有出现的文件正在创建并从NFS挂载中读取include的Makefile中。这个过程本身需要25分钟左右。发布于 2020-08-27 04:35:02
可以提高性能,特别是在使用(gnu) make函数替换shell命令重新生成大量文件时。这将减少完成任务所需的“叉”和“exec”的数量:
%.tgz:
mkdir -p $(<D) && \
$(if $(findstring $(words $^),1),ln -s $^ $@, cat $^ > $@)对于mkdir命令,使用$(<D)将消除对dirname的调用
对于cat/ln命令,使用$(findstring ...)和words将替换echo ... | wc管道,$if(...)将替换shell if语句。
总的来说,每个目标只有两个命令(mkdir,cat/ln),而不是5个命令(mkdir,dirname,echo,wc,cat/ln)。性能约为2倍。
发布于 2020-08-20 23:53:54
Make花了很大一部分准备时间,试图将每个目标与C文件之类的所有内置规则相匹配。添加
.SUFFIXES:
MAKEFLAGS += --no-builtin-rules产生了巨大的变化。在阅读完所有的模式之后,它仍然要花上几分钟时间,但它的好处现在已经超过了成本。
https://stackoverflow.com/questions/63487828
复制相似问题