加速Linux程序编译

标签: 加速 linux 程序 | 发表时间:2010-01-05 14:00 | 作者:Li Fanxi<lifanxi@freemindworld.com> jin
出处:http://www.freemindworld.com

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

  1. 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的开销。

  2. 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不规范,没有正确的设置好依赖关系,并行编译的结果就是编译不能正常进行。如果依赖关系设置过于保守,则可能本身编译的可并行度就下降了,也不能取得最佳的效果。

  3. ccache

  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前面)。

  继续测试:

  用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/.ccache
cache hit                           7165
cache miss                         14283
called for link                       71
not a C/C++ file                     120
no input file                       3045
files in cache                     28566
cache size                          81.7 Mbytes
max cache size                     976.6 Mbytes

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

  4. 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。

相关 [加速 linux 程序] 推荐:

加速Linux程序编译

- jin - 李凡希的Blog
  项目越来越大,每次需要重新编译整个项目都是一件很浪费时间的事情. Research了一下,找到以下可以帮助提高速度的方法,总结一下.   有人说在Windows下用了RAMDisk把一个项目编译时间从4.5小时减少到了5分钟,也许这个数字是有点夸张了,不过粗想想,把文件放到内存上做编译应该是比在磁盘上快多了吧,尤其如果编译器需要生成很多临时文件的话.

Linux程序调试

- - C++博客-首页原创精华区
Linux下的段错误产生的原因及调试方法    原文地址: http://www.upsdn.net/html/2006-11/775.html .    参考地址: http://www.cnblogs.com/khler/archive/2010/09/16/1828349.html .

Linux下第一个驱动程序

- ziche - CSDN博客推荐文章
        因为在Ubuntu环境下写的文章和做的实验,没有安装linux下比较好用的截图工具,所以没有附带太多截屏,还望海涵,不过该描述的都到位了.        曾经还一直处于应用程序开发的我,以为驱动开发者是那么的厉害,以为只有牛人才能走到这一步,随着知识的积累,发现并非如此,驱动开发并不像想象中那么特别,俗话说术业有专攻,开发者只是使用的工具不同,且从事的领域不同,产品不同罢了.

Nginx使用Linux内存加速静态文件访问

- - IT技术博客大学习
标签:   Nginx. Nginx是一个非常出色的静态资源web服务器. 如果你嫌它还不够快,可以把放在磁盘中的文件,映射到内存中,减少高并发下的磁盘IO. nginx.conf中所配置站点的路径是/home/wwwroot/res,站点所对应文件原始存储路径:/opt/web/res. shell脚本非常简单,思路就是拷贝资源文件到内存中,然后在把网站的静态文件链接指向到内存中即可.

从C源程序到Linux可执行程序之旅的四个阶段

- redhobor - 译言-每日精品译文推荐
编写一个C程序,使用gcc进行编译,然后得到一个可执行程序. 你有没有问过自己,编译处理期间到底发生了什么事情,还有C程序如何转换成可执行程序呢. 为了最后变成可执行程序,源代码要经过的行程主要有四个阶段. C源程序变成可执行程序的四个阶段如下:. 预处理编译汇编链接本文第一部分将讨论gcc编译器在把C程序的源代码编译成可执行程序时所经历的步骤.

程序员选择Mac OS多于Linux,Windows最多

- tinda - Solidot
对程序员开发环境的调查显示,选择Mac OS的作为开发环境的程序员多于Linux,但Windows的使用者最多. Evans Data调查了超过400名专业软件开发者,结果发现,80%的人使用Windows,7.9%的人用Mac OS,5.6%的人用Linux. 调查结果还发现,开发者相信未来三年移动和云开发将会越来越重要,44%的人从事多线程程序的开发,49%的人有意支持智能手机平台,42%的人考虑支持平板应用.

Linux系统与程序监控工具atop教程

- - 博客园_首页
Linux以其稳定性,越来越多地被用作服务器的操作系统(当然,有人会较真地说一句:Linux只是操作系统内核:). 但使用了Linux作为底层的操作系统,是否我们就能保证我们的服务做到7*24地稳定呢. 非也,要知道业务功能是由系统上跑的程序实现的,要实现业务功能的稳定性,选择Linux只是迈出的第一步,我们更多地工作是不让业务程序成为稳定性的短板.

每一个程序员需要了解的10个Linux命令

- - 极客521 | 极客521
码农网原创翻译,转载请看清文末的转载要求,谢谢合作. 作为一个程序员,在软件开发职业生涯中或多或少会用到Linux系统,并且可能会使用Linux命令来检索需要的信息. 本文将为各位开发者分享10个有用的Linux命令,希望对你会有所帮助. 以下就是今天我们要介绍的Linux命令:. 接下来让我们逐一来详细介绍.

Linux及Arm-Linux程序开发笔记(零基础入门篇) - 一点一滴的Beer - 博客园

- -
一、Arm-Linux程序开发平台简要介绍. 1.1程序开发所需系统及开发语言. 二、Linux开发平台搭建. 2.2安装Linux虚拟机. 2.3虚拟机的一些基本配置. 三、Fedora-linux系统. 3.1控制终端的基本操作命令. 3.2.2 Qt库及Qt界面设计软件. 四、使用Eclipse CDT开发Linux程序.

Linus Torvalds,当今最著名的程序员之一,Linux内核的创建者, Git的创建者

- wwq0327 - TopGeek
“有些人生来就具有统率百万人的领袖风范;另一些人则是为写出颠覆世界的软件而生. 唯一一个能同时做到这两 者的人,就是Linus Torvalds. ”这是美国《时代》周刊对Linux之父Linus的评价. Linus除了是一位IT奇才外,还是一个乐观幽默的学者. Linus Trovalds很少在会议上露面,站在拥挤的人群面前演讲对他而言是少之又少.