`
quanminchaoren
  • 浏览: 922750 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Android基于distcc的分布式编译及负载均衡的实现

 
阅读更多

distcc简介

distcc

distcc源起于著名开源项目samba,是一款有着较长历史的跨平台开源分布式编译解决方案。

对于大多数c语言及其衍生语言来说,编译过程主要分为三个步骤:

  1. 预编译
  2. 编译
  3. 链接

distcc的作用就是将第二步的编译(3.0版本后通过pump支持部分第一步)过程采用网格计算的模式,将编译任务分配至其它主机,并在编译结束后回传,以供第三步链接使用。并由此降低了发起编译的机器的负载,并提升了编译效率。

distcc本身事实上并不参与任何编译过程,而只是一个编译器(gcc等)的前端。为编译器加入分布式特性,并参与部分管理和简单的负载均衡的功能。根据官方说法,其性能提升的极限阈值是3倍速度,即根据编译池的扩大,无限接近但无法达到原始编译速度的三分之一。

截至目前为止,distcc仅支持c语言及其衍生的c++,Objective-c等的编译。无法支持Java的分布式编译。

pump

自distcc版本3.0开始,加入了基于python的新工具pump。其功能是将头文件也随同源码一起发送至编译服务器。将部分预编译工作也进行分布式处理。从而进一步的提升了编译效率。官方给出的数字是对于文件传输、编译过程有10倍的效率提升。

但pump模式的局限之处在于:在整个编译过程中,源代码(尤其是头文件)不能进行改动,否则会造成错误的编译结果。

ccache

ccache同样产生于samba项目,其作用是将编译过程中的中间文件根据预编译结果,通过hash表索引进行缓存。Ccache具有以下特性:

 

  1. 在命中/缺失上是静态的
  2. 自动的缓存大小管理
  3. 可以缓存产生的编译警告
  4. 容易安装
  5. 很低的开销
  6. 可以使用硬联接来避免复制与distcc不同,ccache是android官方直接支持的编译加速方案。

dmucs

dmucs是为distcc服务的分布式负载均衡解决方案。原始的distcc仅根据服务器指定的顺序来分配编译任务,无法根据编译池中服务器的负载情况 进行动态的编译任务分配。而dmucs则会将编译池中主机的负载情况通知到dmucs服务主机。并由其根据负载及编译机承担能力,动态的对编译任务进行分 配。

 

基准测试结果及分析

构建结果分析

图1 展示了不同编译条件下的编译时间。其中,单机的编译参数使用了-j8, 而双机、三机的编译参数则分别为: -j12,-j15

基准测试结果

 

由此图,大致可以总结出以下结论:

  1. distcc对android系统编译起到显著的加速作用,编译时间随着编译池中编译机器数目的增加而基本呈线性下降趋势。因为暂时无法获得更多的主机进行测试。故无法获知边界情况。
  2. 分布式编译的效果在android 4.0的编译过程中体现相对于 2.3更为明显。
  3. pump工具在编译过程中起到的速度提升作用并不明显。估计是因为android的预编译过程牵涉了大量的头文件和依赖关系,分布式得到的速度提升被文件传输过程所抵消。
  4. ccache的加入极大的改善了编译时间。对ccache的使用命中率,针对2.3.7平台,统计结果如下:
    cache hit 878
    cache miss 11494
    called for link 691
    not a C/C++ file 307
    unsupported compiler option 48
    files in cache 22988
    cache size 1.0 Gbytes
    max cache size 20.0 Gbytes

    ccache 初次编译 2.3.7 统计结果

    cache hit 12127
    cache miss 16
    called for link 691
    not a C/C++ file 307
    unsupported compiler option 48
    files in cache 23020
    cache size 1.0 Gbytes
    max cache size 20.0 Gbytes

    ccache 二次编译 2.3.7 统计结果

    由此可见,在第二次编译时(代码未改动),cache的命中率超过了90%。而速度也因此得到大幅度的提升,基本接近初始速度的三倍。对android 4.0版本的速度提升尤为显著。但此数据对平时开发过程中代码有变化的情况仅能起到参考作用。

  5. 在测试过程中,dmucs的加入并未在时间上有效的缩短单编译请求的时间。原因是因为java/c的混合编译,无法根据distcc的推荐方法增加编译 job的数量,也就无法充分体现分布式编译均衡的优势。但根据编译时观察,dmucs确实能有效的控制编译池中编译机器的负载,并根据编译能力进行平均分 配。
  6. 此外,在图表中未能体现的一个结果为:发起编译的客户机平均负载在采用了分布式编译之后,在c类语言编译阶段,均有较为可观的降低。

 

图2展示了在三机分布式条件下编译android 4.0代码,job数目与编译时间的大致关系。

分布式条件下增加Job数目对编译时间的影响


由此可知,单纯增加job数目并不能获取更好的编译时间。具体原因如下述。

存在的问题及后续解决方案的方向

由于android系统的编译过程中同时存在java的编译和c的编译,而distcc又仅支持c类语言的分布式编译。故对于android的分布式编译 获得的效果不如普通纯c类语言项目明显。随着jobs数目的增加,仅能在本机处理的java编译过程反而由于机器硬件机能的限制而拖慢了整体的编译速度, 甚至抵消了由distcc分布式编译获取的益处。

为了解决这个问题,可从以下几个方面入手,进行进一步的改造:

  1. 分割c类语言的编译过程:将整体android编译过程划分为c语言为主和java为主的两个过程,其中c语言的编译过程采用distcc编译,而java语言的编译则因循原来的编译方式。 此方法涉及android编译脚本的修改,实现较为简单。
  2. 修改make的实现,根据调用java/c编译器的不同,动态的调整作业数目。此改动可能涉及编译脚本修改甚至make源代码修改,实现稍微复杂。
  3. 将java编译过程同样进行分布式处理。可能的方式是在不同的主机上对不同的java项目进行编译。但需要物理的共享存储以及编译脚本修改。实现更为复杂。但仍在可行的范围内。

分布式负载均衡编译环境部署 i

为支持分布式编译,单一编译主机需要进行以下部署步骤:

  1. 安装支持包:  编译主机需要安装distcc、distcc-pump、dmucs包
    1
    
    apt-get
    
    
    
     install
    
    
    
     distcc distcc-pump dumcs
  2. 部署交叉编译工具链至特定位置:
    将android源码自带的prebuilt目录复制到固定地点,比如:/opt/。
  3. 修改distcc的配置文件:
    修改/etc/default/distcc,将
    STARTDISTCC设置为true;
    ALLOWEDNETS为连接的客户端范围,按需设置;
    LISTENER为侦听地址,设置为本机ip地址;
    JOB为同时可承担的编译任务数目,一般设置为CPU个数+2。
    修改/etc/init.d/distcc,将
    PATH参数加入步骤2的交叉编译工具链编译器位置,以使distcc在接到编译任务时,能找到对应的编译器。
  4. 启动distcc服务:  sudo service distcc start

 

发出编译请求的客户端还需要进行如下部署步骤:

 

  1. 创建交叉编译工具至distcc的链接:
    将交叉编译工具全部链接至distcc:

     

    cd
    
    
    
     /
    
    
    
    usr/
    
    
    
    lib/
    
    
    
    distcc
    ln
    
    
    
     -s
    
     ../
    
    
    
    ../
    
    
    
    bin/
    
    
    
    distcc arm-eabi-addr2line
    ln
    
    
    
     -s
    
     ../
    
    
    
    ../
    
    
    
    bin/
    
    
    
    distcc arm-eabi-ar
    ln
    
    
    
     -s
    
     ../
    
    
    
    ../
    
    
    
    bin/
    
    
    
    distcc arm-eabi-as
    ln
    
    
    
     -s
    
     ../
    
    
    
    ../
    
    
    
    bin/
    
    
    
    distcc arm-eabi-c++
    ln
    
    
    
     -s
    
     ../
    
    
    
    ../
    
    
    
    bin/
    
    
    
    distcc arm-eabi-c++filt
    ln
    
    
    
     -s
    
     ../
    
    
    
    ../
    
    
    
    bin/
    
    
    
    distcc arm-eabi-cpp
    ……
  2. 修改android编译脚本,使其支持distcc编译:
    将build/core/combo/TARGET_linux-arm.mk中的TARGET_TOOLS_PREFIX变量改为/usr/lib/distcc/arm-eabi-
    修改build/core/definition.mk, 修改transform-d-to-p为:

     

    define transform-
    
    d-
    
    to-
    
    p
    $
    
    (
    
    hide
    
    )
    
     if [
    
     -
    
    e $
    
    (
    
    @:%.
    
    o=%.
    
    d)
    
     ]
    
    ;
    
    then cp $
    
    (
    
    @:%.
    
    o=%.
    
    d)
    
     $
    
    (
    
    @:%.
    
    o=%.
    
    P)
    
    ;
    
     \
    	sed -
    
    e 's/#.*//'
    
     -
    
    e 's/^[^:]*: *//'
    
     -
    
    e 's/ *\\
    
    
    
    $$//'
    
     \
    		-
    
    e '/^$$/ d'
    
     -
    
    e 's/$$/ :/'
    
     <
    
     $
    
    (
    
    @:%.
    
    o=%.
    
    d)
    
     >>
    
     $
    
    (
    
    @:%.
    
    o=%.
    
    P)
    
    ;
    
     \
    	rm -
    
    f $
    
    (
    
    @:%.
    
    o=%.
    
    d)
    
    ;
    
    else cp $
    
    (
    
    notdir
    
    
    
     $
    
    (
    
    @:%.
    
    o=%.
    
    d)
    
    )
    
     $
    
    (
    
    @:%.
    
    o=%.
    
    P)
    
    ;
    
     \
    	sed -
    
    e 's/#.*//'
    
     -
    
    e 's/^[^:]*: *//'
    
     -
    
    e 's/ *\\
    
    
    
    $$//'
    
     \
    		-
    
    e '/^$$/ d'
    
     -
    
    e 's/$$/ :/'
    
     <
    
     $
    
    (
    
    notdir
    
    
    
     $
    
    (
    
    @:%.
    
    o=%.
    
    d)
    
    )
    
     >>
    
     $
    
    (
    
    @:%.
    
    o=%.
    
    P)
    
    ;
    
     \
    	rm -
    
    f $
    
    (
    
    notdir
    
    
    
     $
    
    (
    
    @:%.
    
    o=%.
    
    d)
    
    )
    
    ;
    
    fi
    endef
  3. 修改环境变量:
    修改PATH,将distcc编译器路径加入PATH的第一个,并加入交叉编译器路径:
    export PATH=/usr/lib/distcc:<上述第二步交叉编译工具链位置>:$PATH
    此命令可写入profile。
    修改DISTCC_HOSTS,指明支持分布式编译的主机地址:
    export DISTCC_HOSTS=’localhost … … ‘
  4. 发起编译过程:
    make -j8 CC=distcc 根据编译池主机数和本机资源情况调整job数目,以获取最佳性能。

与ccache配合使用

因android官方已经在构建环境中加入了ccache支持,故可以很简单的打开ccache功能以提高编译效率。具体方法为:

$ export



 USE_CCACHE

=1


$ export



 CCACHE_DIR

=/



path_of_your_choice/



.ccache
$ prebuilt/



linux-x86/



ccache/



ccache -M

 20G

其中,20G为推荐值,事实上可以根据编译机器的具体情况进行调整。

在编译期或编译结束后,可以用“ccache -s ”命令查看缓存命中情况。

用dmucs实现负载均衡

选中某台主机作为dmucs服务器。进行配置:

  1. 修改/etc/default/dmucs,启用dmucs:
    将SERVER改为yes
  2. 修改/etc/dmucs.conf 文件,配置编译池:
    根据文件原有说明格式,加入编译池中的主机。
  3. 启动dmucs服务:
    service start dmucs
  4. 在每个编译主机上执行负载发布客户端:
    loadavg -s 主机地址 &

此时,即可以在发起编译时使用

make -j8 CC=gethost distcc

来启用支持负载均衡的分布式编译过程了。

 

FAQ

  1. 执行pump时报python错误 这是一个已知的bug,解决方法参见https://bugs.launchpad.net/distcc/+bug/511585
  2. 编译时pump报主机不支持cpp
    在创建环境变量时需要指明主机支持的编译类型如:
    export DISTCC_HOSTS=’localhost compilehost,lzo,cpp’

参考文献

  1. distcc官方网站:http://code.google.com/p/distcc/
  2. distcc官方文档:http://distcc.googlecode.com/svn/trunk/doc/web/index.html
  3. 《分布式编译环境中的负载均衡 》:http://www.ibm.com/developerworks/cn/aix/library/0905_yangyi_distcc/index.html
  4. dmucs官方网站:http://dmucs.sourceforge.net
分享到:
评论

相关推荐

    分布式编译工具distcc-2.18.3

    distcc-2.18.3 分布式编译工具 distcc-2.18.3 分布式编译工具

    计算智能技术在分布式多编译器中的应用分析.pdf

    1. **任务调度优化**:利用模糊逻辑或遗传算法来动态调整任务分配,确保负载均衡,避免资源浪费。 2. **网络通信优化**:通过神经网络预测网络状态,优化数据传输策略,减少通信延迟。 3. **错误恢复机制**:采用...

    distcc-3.2rc1.tar.gz

    它的工作原理是将源代码的编译过程分解为预处理、编译、汇编和链接四个步骤,然后将其中的编译和汇编部分分发到网络上的其他机器上进行,最后再将结果汇总到本地进行链接,从而实现编译速度的提升。 在distcc 3.2rc...

    icecream:带有中央调度程序的分布式编译器可共享构建负载

    是由SUSE基于distcc创建的。 像distcc一样, 从构建中获取编译作业,并将其分配到允许并行构建的远程计算机之间。 但是与distcc不同, 使用中央服务器动态地将编译作业调度到最快的免费服务器。 这种优势主要为共享...

    distcc-2.18.3.rar

    《分布式编译加速神器:distcc 2.18.3 深度解析》 在软件开发领域,编译速度对于项目进度有着至关重要的影响。当面对大规模代码库时,传统的单机编译方式可能会耗费大量时间。为了解决这个问题,一种名为“分布式...

    distcc introduction

    2. **自动负载均衡**:`distcc`能够自动检测网络中的可用机器,并将编译任务智能分配给当前负载较低的节点。 3. **错误恢复能力**:即使某台机器出现故障,`distcc`也能自动重新调度受影响的任务到其他可用节点,...

    distcc的配置

    distcc 是一种分布式编译器,可以将多台电脑联合起来,一起编译程序,以解决单机编译慢的问题。下面是 distcc 的配置和使用方法: 1. 安装 distcc distcc 可以从 Debian 软件中心或是 http://distcc.samba.org/...

    C++联合编译工具 实测好用

    3. **分布式编译**:对于非常大的项目,可以使用如DistCC或Jenkins等工具,将编译任务分发到网络中的多台机器上,实现跨机器的并行编译。 4. **预编译头文件(Precompiled Header, PCH)**:PCH是另一种提高编译...

    distccd_dmucs.zip

    总的来说,distcc和dmucs是提高开发效率的有力工具,它们可以帮助开发者有效地利用多台机器的计算资源,实现编译过程的并行化。然而,正确配置和使用这些工具需要一定的学习和实践,包括理解其工作原理、解决可能...

    distcc:适用于C,C ++和Objective C的分布式构建

    一个免费的分布式C / C ++编译器系统 马丁·波尔当前文档: : 正式 Fergus Henderson,Nils Klarlund,Manos Renieris和Craig Silverstein(Google Inc.)添加了“泵”功能distcc是一个程序,用于在网络上的多台...

    并行编译工具Icecream.zip

    Icecream 是由 SUSE 创建的、基于 distcc 的并行编译工具。可在远程机器上执行构建和分发、并行编译。与 distcc 不同的是,Icecream 使用一个中央服务器动态的对编译作业进行调度。 标签:Icecream

    DistccTracker-开源

    DistccTracker是一款基于Java开发的开源工具,专为Distcc分布式编译系统设计的服务器跟踪器。Distcc(Distributed C/C++ Compiler)是一个能够将编译任务分发到网络中多台计算机的系统,从而加快编译速度,提高开发...

    c#毕业设计源码下载-distcc:C,C++和ObjectiveC的分布式构建

    c#毕业设计源码下载distcc-一个免费的分布式C / C ++编译器系统 马丁·波尔(Martin Pool) 当前文件:正式 Fergus Henderson,Nils Klarlund,Manos Renieris和Craig Silverstein(Google Inc.)添加了“泵”功能 ...

    Distcc Netboot Node-开源

    Distcc Netboot Node是一个基于Gentoo Linux的开源项目,专为实现分布式C编译器——Distcc的高效运行而设计。它是一个网络引导节点,能够帮助构建大规模的跨计算机集群,以加速软件开发过程中的编译环节。通过将编译...

    distcc_detection.nasl

    distcc_detection

    提高编绎速度的方法集合.txt

    Linux程序编译速度提高方法 使用distcc和ccache缩短C/C++项目编译时间 如何让 Xcode 在读写上提速100倍? 全民K歌后台编译优化:从40分钟到30秒 编译环境+工程放在内存虚拟的硬盘里比机械硬盘运行速度提升不少

    retroroller:适用于odroid的RetroRoller前进

    拉尔 特别感谢: Safarikniv托管 npaladin2000(dev) ...启用distcc进行分布式编译 Distfiles镜像 交叉编译目标体系结构的软件包 在国外Linux发行版中使用xbps-src 重建主目录 保持您的主目录最

    BuildPP-开源

    它不仅仅是一个简单的构建工具,还特别注重跨平台兼容性和多线程编译的优化,同时支持分布式编译工具distcc,从而极大地提高了构建效率。 首先,让我们深入了解一下BuildPP的工作原理。它通过扫描源代码文件来识别...

    distccForXCode:使 distcc 在 XCode 中工作

    distccForXCode 使 distcc 在 XCode 中工作 客户端:quick_client.sh 服务器:quick_server.sh 如果你不想使用它,:restoreLLVM.sh

Global site tag (gtag.js) - Google Analytics