免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5709 | 回复: 3
打印 上一主题 下一主题

用Makefile实现并行任务分发 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-12-14 02:22 |只看该作者 |倒序浏览
本帖最后由 vupiggy 于 2010-12-14 15:21 编辑

看到关于Makefile的必要性讨论,忽然想起自己干过一些有趣的的事情。

一个目录下有一大堆同质或不同质的程序,要测试系统处理并发任务的效率不得不写一个任务分发器(work load manager),用C写对新手来说还是有点大条的,利用make -j可以模拟一个简单的wlm。代码大概如下:
  1. binaries := $(foreach ccode, \
  2.               $(shell for cfile in `ls *.c`; do echo $cfile; done),\
  3.               $(ccode:.c=))
  4. $(binaries): %:%.c
  5.         @echo BLD        $@
  6.         @gcc -o $@       $< >/dev/null 2>&1

  7. to_run := $(foreach ccode, \
  8.             $(shell for cfile in `ls *.c`; do echo $cfile; done),\
  9.             to_run_$(ccode:.c=))

  10. run: clean $(to_run)
  11. to_run_%: %
  12.         @to_run=$@;                         \
  13.          echo ${to_run##to_run_};        

  14. clean:
  15.         @echo -n "-------------------------------- CLEAN "
  16.         @echo "--------------------------------"
  17.         @echo RMV        $(binaries)
  18.         @rm -f                 $(binaries)


  19. .PHONY: run clean
复制代码
运行 make -jN 即可

论坛徽章:
7
酉鸡
日期:2013-10-30 17:17:51水瓶座
日期:2014-01-25 14:47:21天秤座
日期:2014-02-20 09:49:50处女座
日期:2014-11-04 17:44:082015年亚洲杯之中国
日期:2015-03-09 17:21:312015亚冠之北京国安
日期:2015-06-01 16:58:552015亚冠之山东鲁能
日期:2015-06-19 11:30:08
2 [报告]
发表于 2010-12-14 12:11 |只看该作者
太高深了,看不明白啊

论坛徽章:
0
3 [报告]
发表于 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
  1. run: clean $(to_run)
复制代码
2. to_run 是由一段 shell 产生的

  1. to_run := $(foreach ccode, \
  2.              $(shell for cfile in `ls *.c`; do echo $cfile; done),\
  3.              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 的规则去(重新)生成它:

  1. $(binaries): %:%.c
  2.          @echo BLD        $@
  3.          @gcc -o $@       $< >/dev/null 2>&1
复制代码
5.  73 生成以后就运行它,示例里用的是 echo
  1. @to_run=$@;                         \
  2.           echo ${to_run##to_run_};   
复制代码
实际上可以是
  1. @to_run=$@;                         \
  2.           ./${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大概可以这样写:
  1. ifeq ($(MAX),)
  2.         MAX=1024
  3. endif

  4. parameter0=0
  5. parameter1=11
  6. parameter2=22
  7. parameter3=33

  8. prerequisites := $(foreach num,                                        \
  9.                    $(shell i=0; while [ $$i -lt $(MAX) ];        \
  10.                                 do                                \
  11.                                         echo $$i;                \
  12.                                         i=$$((i + 1));                \
  13.                                     done),                                \
  14.                   target_$(num))
  15. run:$(prerequisites)

  16. EXEC0: EXEC0.c
  17.         gcc -o $@ $<

  18. target_%:EXEC0
  19.         @./EXEC0 $(parameter$(shell expr $(subst target_,,$@) % 4))

  20. .PHONY: run
复制代码
一个无聊的EXEC0.c 可以是:
  1. int
  2. main(int argc, char **argv)
  3. {
  4.         sleep(atoi(argv[1]));
  5.         printf("%s %d\n", argv[0], atoi(argv[1]));

  6.         return 0;
  7. }
复制代码
然后make -j32 MAX=1024

评分

参与人数 1可用积分 +5 收起 理由
davelv + 5 ++

查看全部评分

论坛徽章:
0
4 [报告]
发表于 2010-12-15 09:23 |只看该作者
果然很高深~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP