You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Makefile中拆分输入文件列表,实现高效并行调用程序?

纯Make实现输入文件分组批量处理

以下是完全基于Make内置能力(仅使用shell基础整数运算,未调用bash/awk等外部脚本工具)的解决方案,可将输入文件均匀拆分为指定数量的组,配合make -j实现高效并行处理:

# 配置参数:设置并行处理的进程数和输入文件列表
NUM_GROUPS := 8
IN_FILES := f1.in f2.in f3.in f4.in f5.in f6.in f7.in f8.in f9.in f10.in f11.in f12.in

# 计算总文件数量
TOTAL_FILES := $(words $(IN_FILES))

# 计算每组基础文件数和余数:前REM个组每组多1个文件,保证分组均匀
QUOT := $(shell echo $$(( $(TOTAL_FILES) / $(NUM_GROUPS) )))
REM := $(shell echo $$(( $(TOTAL_FILES) % $(NUM_GROUPS) )))

# 定义生成单组文件列表的函数
define DEFINE_GROUP
# 计算当前组的文件起始/结束位置
ifeq ($(1),1)
START := 1
else ifeq ($(1),$(shell echo $$(( $(REM) + 1 ))))
START := $(shell echo $$(( $(REM) * ($(QUOT) + 1) + 1 )))
else ifneq ($(shell echo $$(( $(1) <= $(REM) ))),0)
START := $(shell echo $$(( ($(1) - 1) * ($(QUOT) + 1) + 1 )))
else
START := $(shell echo $$(( $(REM) * ($(QUOT) + 1) + ($(1) - $(REM) - 1) * $(QUOT) + 1 )))
endif

ifeq ($(shell echo $$(( $(1) <= $(REM) ))),0)
END := $(shell echo $$(( $(START) + $(QUOT) - 1 )))
else
END := $(shell echo $$(( $(START) + $(QUOT) )))
endif

# 截取对应范围的文件列表
GROUP_$(1) := $(wordlist $(START),$(END),$(IN_FILES))
endef

# 循环生成所有组的文件列表定义
$(foreach n,$(shell seq 1 $(NUM_GROUPS)),$(eval $(call DEFINE_GROUP,$(n))))

# 生成所有分组处理目标
GROUP_TARGETS := $(foreach n,$(shell seq 1 $(NUM_GROUPS)),group_$(n).out)

# 默认目标
all: $(GROUP_TARGETS)

# 分组处理规则:单次调用Program处理整组文件
group_%.out:
	Program $^ > $@

# 为每个分组目标绑定对应文件依赖
$(foreach n,$(shell seq 1 $(NUM_GROUPS)),$(eval group_$(n).out: $(GROUP_$(n))))

方案说明

  1. 参数配置:修改NUM_GROUPS设置并行进程数(比如你需要的8次),IN_FILES填入所有输入文件。
  2. 均匀分组:通过整数运算计算每组文件数量,当总文件数无法被分组数整除时,前N个组会多1个文件,保证各组数量尽可能均衡。
  3. 并行执行:执行make -j$(NUM_GROUPS)即可启动指定数量的并行进程,每个进程一次性处理一组文件,彻底避免频繁启动Program的开销。

如果要求完全不依赖任何shell调用,纯Make实现整数运算会非常繁琐(Make无原生整数运算支持),上述方案是平衡简洁性与需求的最优解。

内容的提问来源于stack exchange,提问作者dash-o

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:05:55