Chinaunix
标题:
用Makefile实现并行任务分发
[打印本页]
作者:
vupiggy
时间:
2010-12-14 02:22
标题:
用Makefile实现并行任务分发
本帖最后由 vupiggy 于 2010-12-14 15:21 编辑
看到关于Makefile的必要性讨论,忽然想起自己干过一些有趣的的事情。
一个目录下有一大堆同质或不同质的程序,要测试系统处理并发任务的效率不得不写一个任务分发器(work load manager),用C写对新手来说还是有点大条的,利用make -j可以模拟一个简单的wlm。代码大概如下:
binaries := $(foreach ccode, \
$(shell for cfile in `ls *.c`; do echo $cfile; done),\
$(ccode:.c=))
$(binaries): %:%.c
@echo BLD $@
@gcc -o $@ $< >/dev/null 2>&1
to_run := $(foreach ccode, \
$(shell for cfile in `ls *.c`; do echo $cfile; done),\
to_run_$(ccode:.c=))
run: clean $(to_run)
to_run_%: %
@to_run=$@; \
echo ${to_run##to_run_};
clean:
@echo -n "-------------------------------- CLEAN "
@echo "--------------------------------"
@echo RMV $(binaries)
@rm -f $(binaries)
.PHONY: run clean
复制代码
运行 make -jN 即可
作者:
syncpk99
时间:
2010-12-14 12:11
太高深了,看不明白啊
作者:
vupiggy
时间:
2010-12-14 23:57
本帖最后由 vupiggy 于 2010-12-14 17:06 编辑
太高深了,看不明白啊
syncpk99 发表于 2010-12-14 05:11
简而言之就是:
1. default 的 target 是 run,run 依赖于 clean 和 to_run
run: clean $(to_run)
复制代码
2. to_run 是由一段 shell 产生的
to_run := $(foreach ccode, \
$(shell for cfile in `ls *.c`; do echo $cfile; done),\
to_run_$(ccode:.c=))
复制代码
3. 假设目录下有 1.c 2.c 3.c 4.c ... 100.c 这100个c程序, 那段 shell 生成的变量 to_run 等于这样的一串: to_run_1 to_run2 ... to_run_100
4. to_run_%: % 那一段 rule 的意思是对于某个目标 to_run_73 依赖于 73,当 73 不存在或者 73.c 被更新过, make 就按照上面声明的 binaries 的规则去(重新)生成它:
$(binaries): %:%.c
@echo BLD $@
@gcc -o $@ $< >/dev/null 2>&1
复制代码
5. 73 生成以后就运行它,示例里用的是 echo
@to_run=$@; \
echo ${to_run##to_run_};
复制代码
实际上可以是
@to_run=$@; \
./${to_run##to_run_};
复制代码
这样 73 就在适当的时候被运行了。
假设输入 make -j32 run,结果就是可执行文件 1, 2, 3 ... 32 同时被运行,其中的某个结束后 make 会自动启动后面的 33, 34 ... 直至所有的运行结束,这就模拟了一个简单的本地 work load manager。
这个make脚本的另外一个变种可以是:你有一个程序(假设叫 EXEC0),在一台16核的机器上你希望并行地运行32个带不同参数的 EXEC0 实例,总共运行 1024 个实例来测试系统或者 EXEC0 的运行效率,Makefile大概可以这样写:
ifeq ($(MAX),)
MAX=1024
endif
parameter0=0
parameter1=11
parameter2=22
parameter3=33
prerequisites := $(foreach num, \
$(shell i=0; while [ $$i -lt $(MAX) ]; \
do \
echo $$i; \
i=$$((i + 1)); \
done), \
target_$(num))
run:$(prerequisites)
EXEC0: EXEC0.c
gcc -o $@ $<
target_%:EXEC0
@./EXEC0 $(parameter$(shell expr $(subst target_,,$@) % 4))
.PHONY: run
复制代码
一个无聊的EXEC0.c 可以是:
int
main(int argc, char **argv)
{
sleep(atoi(argv[1]));
printf("%s %d\n", argv[0], atoi(argv[1]));
return 0;
}
复制代码
然后make -j32 MAX=1024
作者:
veking
时间:
2010-12-15 09:23
果然很高深~
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2