[讨论] 如何加快linux android 的编译速度

Wince.Android   2013-6-27 14:50 楼主
尤其是android4.0 编译,很难顶吧,四个小时一般的电脑,有什么办法优化一下呢?
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460

回复评论 (13)

  项目越来越大,每次需要重新编译整个项目都是一件很浪费时间的事情。Research了一下,找到以下可以帮助提高速度的方法,总结一下。

       1. 使用tmpfs来代替部分IO读写

  2.ccache,可以将ccache的缓存文件设置在tmpfs上,但是这样的话,每次开机后,ccache的缓存文件会丢失

  3.distcc,多机器编译

  4.将屏幕输出打印到内存文件或者/dev/null中,避免终端设备(慢速设备)拖慢速度。


 tmpfs

  有人说在Windows下用了RAMDisk把一个项目编译时间从4.5小时减少到了5分钟,也许这个数字是有点夸张了,不过粗想想,把文件放到内存上做编译应该是比在磁盘上快多了吧,尤其如果编译器需要生成很多临时文件的话。

  这个做法的实现成本最低,在Linux中,直接mount一个tmpfs就可以了。而且对所编译的工程没有任何要求,也不用改动编译环境。

  mount -t tmpfs tmpfs ~/build -o size=1G

  用2.6.32.2的Linux Kernel来测试一下编译速度:

  用物理磁盘:40分16秒

  用tmpfs:39分56秒

  呃……没什么变化。看来编译慢很大程度上瓶颈并不在IO上面。但对于一个实际项目来说,编译过程中可能还会有打包等IO密集的操作,所以只要可能,用tmpfs是有益无害的。当然对于大项目来说,你需要有足够的内存才能负担得起这个tmpfs的开销。

  make -j

  既然IO不是瓶颈,那CPU就应该是一个影响编译速度的重要因素了。

  用make -j带一个参数,可以把项目在进行并行编译,比如在一台双核的机器上,完全可以用make -j4,让make最多允许4个编译命令同时执行,这样可以更有效的利用CPU资源。

  还是用Kernel来测试:

  用make: 40分16秒

  用make -j4:23分16秒

  用make -j8:22分59秒

  由此看来,在多核CPU上,适当的进行并行编译还是可以明显提高编译速度的。但并行的任务不宜太多,一般是以CPU的核心数目的两倍为宜。

  不过这个方案不是完全没有cost的,如果项目的Makefile不规范,没有正确的设置好依赖关系,并行编译的结果就是编译不能正常进行。如果依赖关系设置过于保守,则可能本身编译的可并行度就下降了,也不能取得最佳的效果。

  ccache

ccache工作原理:
ccache也是一个编译器驱动器。第一趟编译时ccache缓存了GCC的“-E”输出、编译选项以及.o文件到$HOME/.ccache。第二次编译时尽量利用缓存,必要时更新缓存。所以即使"make clean; make"也能从中获得好处。ccache是经过仔细编写的,确保了与直接使用GCC获得完全相同的输出。

  ccache用于把编译的中间结果进行缓存,以便在再次编译的时候可以节省时间。这对于玩Kernel来说实在是再好不过了,因为经常需要修改一些Kernel的代码,然后再重新编译,而这两次编译大部分东西可能都没有发生变化。对于平时开发项目来说,也是一样。为什么不是直接用make所支持的增量编译呢?还是因为现实中,因为Makefile的不规范,很可能这种“聪明”的方案根本不能正常工作,只有每次make clean再make才行。

  安装完ccache后,可以在/usr/local/bin下建立gcc,g++,c++,cc的symbolic link,链到/usr/bin/ccache上。总之确认系统在调用gcc等命令时会调用到ccache就可以了(通常情况下/usr/local /bin会在PATH中排在/usr/bin前面)。

  安装的另外一种方法:

  vi ~/.bash_profile

  把/usr/lib/ccache/bin路径加到PATH下

  PATH=/usr/lib/ccache/bin:$PATH:$HOME/bin

  这样每次启动g++的时候都会启动/usr/lib/ccache/bin/g++,而不会启动/usr/bin/g++

  效果跟使用命令行ccache g++效果一样

  这样每次用户登录时,使用g++编译器时会自动启动ccache

  继续测试:

  用ccache的第一次编译(make -j4):23分38秒

  用ccache的第二次编译(make -j4):8分48秒

  用ccache的第三次编译(修改若干配置,make -j4):23分48秒


看来修改配置(我改了CPU类型...)对ccache的影响是很大的,因为基本头文件发生变化后,就导致所有缓存数据都无效了,必须重头来做。但如果只是修改一些.c文件的代码,ccache的效果还是相当明显的。而且使用ccache对项目没有特别的依赖,布署成本很低,这在日常工作中很实用。

  可以用ccache -s来查看cache的使用和命中情况:

  cache directory           /home/lifanxi/.ccachecache hit              7165cache miss             14283called for link            71not a C/C++ file           120no input file            3045files in cache           28566cache size              81.7 Mbytesmax cache size           976.6 Mbytes

  可以看到,显然只有第二编次译时cache命中了,cache miss是第一次和第三次编译带来的。两次cache占用了81.7M的磁盘,还是完全可以接受的。

  distcc

  一台机器的能力有限,可以联合多台电脑一起来编译。这在公司的日常开发中也是可行的,因为可能每个开发人员都有自己的开发编译环境,它们的编译器版本一般是一致的,公司的网络也通常具有较好的性能。这时就是distcc大显身手的时候了。

  使用distcc,并不像想象中那样要求每台电脑都具有完全一致的环境,它只要求源代码可以用make -j并行编译,并且参与分布式编译的电脑系统中具有相同的编译器。因为它的原理只是把预处理好的源文件分发到多台计算机上,预处理、编译后的目标文件的链接和其它除编译以外的工作仍然是在发起编译的主控电脑上完成,所以只要求发起编译的那台机器具备一套完整的编译环境就可以了。

  distcc安装后,可以启动一下它的服务:

  /usr/bin/distccd  --daemon --allow 10.64.0.0/16

  默认的3632端口允许来自同一个网络的distcc连接。

  然后设置一下DISTCC_HOSTS环境变量,设置可以参与编译的机器列表。通常localhost也参与编译,但如果可以参与编译的机器很多,则可以把localhost从这个列表中去掉,这样本机就完全只是进行预处理、分发和链接了,编译都在别的机器上完成。因为机器很多时,localhost的处理负担很重,所以它就不再“兼职”编译了。

  export DISTCC_HOSTS="localhost 10.64.25.1 10.64.25.2 10.64.25.3"

  然后与ccache类似把g++,gcc等常用的命令链接到/usr/bin/distcc上就可以了。

  在make的时候,也必须用-j参数,一般是参数可以用所有参用编译的计算机CPU内核总数的两倍做为并行的任务数

  同样测试一下:

  一台双核计算机,make -j4:23分16秒

  两台双核计算机,make -j4:16分40秒

  两台双核计算机,make -j8:15分49秒

  跟最开始用一台双核时的23分钟相比,还是快了不少的。如果有更多的计算机加入,也可以得到更好的效果。

  在编译过程中可以用distccmon-text来查看编译任务的分配情况。distcc也可以与ccache同时使用,通过设置一个环境变量就可以做到,非常方便。

  总结一下:

   tmpfs: 解决IO瓶颈,充分利用本机内存资源

  make -j: 充分利用本机计算资源

  distcc: 利用多台计算机资源

  ccache: 减少重复编译相同代码的时间

  这些工具的好处都在于布署的成本相对较低,综合利用这些工具,就可以轻轻松松的节省相当可观的时间。上面介绍的都是这些工具最基本的用法,更多的用法可以参考它们各自的man page。

  5.还有提速方法是把屏幕输出重定向到内存文件或/dev/null,因对终端设备(慢速设备)的阻塞写操作也会拖慢速度。推荐内存文件,这样发生错误时,能够查看。


------------------------------------------------------------------------------------------


看了embedded android发现这个ccache的使用方式,可以加速我们c与c++的编译速度原理就是中间文件的一个缓存,是同一个.o文件的话就省去再次编译的速度。
介于android中c与c++文件数量能占到刚不到一半,所以这个速度还是能省下很多的。
看到原理大概也就是知道这个东西第一次编译是没有效果的,只有开启ccache后编译一次后就会有效果。
使用方式:
添加环境变量:
1.$ export USE_CCACHE=1
#建立缓存目录
2.$ export CCACHE_DIR=~/.ccache
设置缓存大小:
3.$cd android/
4.$prebuilt/linux-x86/ccache/ccache -M 20G
You can watch ccache being used by doing the following:
$ watch -n1 -d prebuilt/linux-x86/ccache/ccache -s





摘自官网》》》http://source.android.com/source/initializing.html#ccache

Setting up ccache

You can optionally tell the build to use the ccache compilation tool.Ccache acts as a compiler cache that can be used to speed-up rebuilds.This works very well if you do "make clean" often, or if you frequentlyswitch between different build products.

Put the following in your .bashrc or equivalent.

export USE_CCACHE=1

By default the cache will be stored in ~/.ccache.If your home directory is on NFS or some other non-local filesystem,you will want to specify the directory in your .bashrc as well.

export CCACHE_DIR=

The suggested cache size is 50-100GB.You will need to run the following command once you have downloadedthe source code.

prebuilt/linux-x86/ccache/ccache -M 50G

This setting is stored in the CCACHE_DIR and is persistent.

如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
点赞  2013-6-27 14:56
内核加速方法  
1.安装ccache  
apt-get install ccache  
2.添加缓存路径  
vi ~/.bashrc 再最后面添加一行指定缓存路径  
export CCACHE_DIR=/opt/ccache  
3.测试  
make clean 后make zImage 就生效。  
用 time make zImage -jx来测试 看看时间的变化
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460
点赞  2013-6-27 15:59
用固态硬盘有效果吗?
点赞  2013-6-27 16:14

回复 4楼cat3902982 的帖子

这类编译过程存在大量的外部数据交换,这样的应用采用在固态盘上运行可以有效改善整体处理时间。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
点赞  2013-6-27 16:39

回复 4楼 cat3902982 的帖子

有,会快不少的。不过咱的电脑还是双核的,所以必须考虑用一些东西去改善。
点赞  2013-6-27 22:58

回复 5楼 chunyang 的帖子

+++是的,效果很明显的, 只是固态硬盘太贵了。
最近也想入手一个笔记本啊,I5+8G 内存的配置才能用的爽了。
点赞  2013-6-27 22:59

回复 7楼gooogleman 的帖子

现在的CPU处理能力已过剩,买i5的钱足以换成赛扬(比如新推出的IVB架构的赛扬G1610等)+120G固态盘,在绝大多数应用中,赛扬+固态盘完胜i5甚至i7。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
点赞  2013-6-28 12:15
引用: 原帖由 chunyang 于 2013-6-28 12:15 发表
现在的CPU处理能力已过剩,买i5的钱足以换成赛扬(比如新推出的IVB架构的赛扬G1610等)+120G固态盘,在绝大多数应用中,赛扬+固态盘完胜i5甚至i7。
没有过剩啊,这个处理器还是很重要的。
固态硬盘这个还要便宜一些才行。
点赞  2013-6-29 18:08

回复 9楼gooogleman 的帖子

CPU处理能力是否过剩的判别依据是CPU的平均占用率,打开Windows任务管理器或者使用AIDA之类的软件即可进行监视。就绝大多数人使用计算机的绝大多数时候,如果CPU的占用率普遍在50%以下,那么说明CPU的处理能力已经过剩了。
以我的计算机为例,我最新组装的计算机CPU是Intel 赛扬G1610,使用Win7 64位操作系统,平时工作时的CPU占用率在3%-7%之间,显然,就第三代Core i处理器的最低端型号G1610而言,处理能力已经过剩。因为我同时还是摄影爱好者,只有在使用PS进行数字底片批处理时CPU的占用率才会较高,但这种操作是很罕见的。就编译代码之类的而言,CPU占用率不会比PS更高。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
点赞  2013-6-29 22:14
再次强调,同样支出下,i5的价格已经可以购买赛扬+固态盘了,而赛扬+固态盘对多数应用的体验都完爆i5,除非你不差钱或不在乎。
我虽然不差那个钱,但我在乎性价比。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
点赞  2013-6-29 22:18
关于CPU处理能力是否过剩的问题再补充一点:现在的CPU都支持由BIOS和操作系统控制的功耗管理,以Intel的CPU为例,当CPU占用率较低时,操作系统会自动降低CPU的时钟,此时第三代Core i的时钟为1600MHz,第四代Core i的时钟甚至仅仅为800MHz,这意味着,在低CPU占用下,第三代Core i核心的CPU不管i5(双核i5)还是i3都和赛扬一样是1600MHz的双核处理器,至强、i7、i5(四核i5)都是1600MHz的四核处理器,大家已经彼此彼此了。即便如此,Intel发现1600MHz的低负荷主频仍然白白浪费了CPU资源,所以将刚刚推出的第四代Core i处理器的闲置主频降低到800MHz,这意味着在低CPU占用率下,第四代Core i处理器哪怕是最高档的,其实际处理能力甚至明显低于第三代Core i的低端型号,也就是说这种时候新的i7恐怕还不如旧的赛扬,呵呵……
在EEWorld浏览及回帖时,俺的CPU平均占用率为3%,此时的CPU主频一直处于1600MHz下,功耗约19W。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
点赞  2013-6-29 22:39
引用: 原帖由 chunyang 于 2013-6-29 22:14 发表
CPU处理能力是否过剩的判别依据是CPU的平均占用率,打开Windows任务管理器或者使用AIDA之类的软件即可进行监视。就绝大多数人使用计算机的绝大多数时候,如果CPU的占用率普遍在50%以下,那么说明CPU的处理能力已经过 ...
虚拟机占用很大很大的,PS 小case 了。主要是虚拟机,其他都好说。虚拟机要4G 内存 I5 以上才好点,如果是双核的,那可是很挫的。很慢的。
点赞  2013-7-2 23:50

回复 13楼gooogleman 的帖子

呵呵,内存和处理器可是完全不同的两回事哦。用虚拟机是对CPU和内存有更高的要求,但也不绝对,凡事都有理论依据并可经实践证明,不可只凭感觉。
同样价格下,赛扬+固态盘比拼i5甚至i7、至强,哪个更有价值,你试过就知道了。就很多人的感觉而言,固态盘太贵,i5、i7就不觉得那么贵,其实,实验一下、计算一下,真相大白。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
点赞  2013-7-3 00:55
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复