加速Linux程序编译

项目越来越大,每次需要重新编译整个项目都是一件很浪费时间的事情。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的开销。

  • 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用于把编译的中间结果进行缓存,以便在再次编译的时候可以节省时间。这对于玩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的磁盘,还是完全可以接受的。

  • 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。

2010新年好

2010年的第一个工作日结束了。元旦期间忙着玩,没来得及写迎新年的博客,今天补上。

2009年,我做了这些事情:

– 写了13篇博客。

博客空间总访问量13649 PageView,其中“豆饭”插件的页面在上半年贡献了全年40%的PV。

– 参与了两个自由软件项目

用于同步Google Calendar和Windows Mobile手机Calendar的GMobileSync和Windows Moible手机上的Twitter/饭否客户端软件PockeTwit

– 发起了一个自由软件项目

LGuo的电子运行图,用于绘制火车运行图。这个软件是LGuo开发的,我现在协助他把这个软件转变为一个自由软件。工作仍在进行中。

– 买了个两个重要的IT产品

可以用来离线下载的小NAS盒子WD My Book World Edition

新的笔记本电脑:Lenovo ThinkPad T400 2767-R84,取代了陪伴了我近5年的ThinkPad T42 2373-NTH。

– 铁路相关活动

铁路运转里程7419公里,台湾高铁运转359公里。送别Z50次列车。参观了中国铁道博物馆

– 旅游

无锡灵山/太湖两日游台湾6日游。南京各大景点多日游,比如:梅花山

2010年,要做这些事情:

– 学开车

2008年7月报的名,10月考了交规,今年10月就要到2年的期限了,一定不能浪费了。

– 简单理财

2009总的开销中,房租和IT产品占了50%,这不可怕,可怕的是占总开销16%的“取现消费”完全不知道用到哪里去了。

– 进一步的时间管理

2009年中很有几个月非常的低效,提高效率是当务之急。

零零总总,2009年虽是平淡的一年,却又在这一年中发生了很多我自己意料之外的事情,有些事情甚至于非常的困扰,不过终于还是平安的走过了,期待2010。

2009年的最后一天,去车站接人,顺便买了张有点特别的火车票玩:10年01月01日 00:00 开车,票价10元。

10年01月01日 00:00开车的火车票

10年01月01日 00:00开车的火车票

过马路

回家路上发生件事,记之,兼引别的事。

下公交车到家,需要横穿一条马路,那里的交通灯是区分直行和左转车辆的,但那个路口又几乎没有左转车辆,左转车道绿灯时人行道灯还是红的,所以几乎每天在那里都会“浪费”20秒时间,面对空无一车的马路,等人行道灯变绿后再过马路。

今天在这个路口,我按惯例等红灯。但边上的交警叔叔(也有可能是辅警)说:“走走走,没得车子。”听了他的话,不知道是为了给他面子,还是给自己面子,我就迎着红灯过了马路。我承认我并不是100%没有闯过红灯,但今天这路走得确觉得特别的别扭,特别的不踏实,甚至可以说是心惊胆战。

以后还是依着自己的本性做事情吧。

关注2010维也纳新年音乐会

继续维持传统,第六次写名为关注xxxx维也纳新年音乐会的Blog。前几篇在:2005 2006 2007 2008 2009

昨天Südwestrundfunk(德国西南广播电台)在网站公布了2010年维也纳新年音乐会的曲目单,如下:

01 – Johann Strauss II – Die Fledermaus; Overtüre – 蝙蝠序曲

02 – Josef Strauss – Frauenherz; Polka Mazur; op. 166 – 女人心玛祖卡波尔卡

03 – Johann Strauss II – Im Krapfenwald’l; Polka francaise; op. 336 – 在克拉芬得森林法兰西波尔卡

04 – Johann Strauss II – Stürmisch in Lieb’ und Tanz; Polka schnell; op. 393 – 激烈的爱情与舞蹈快速波尔卡

05 – Johann Strauss II – Wein, Weib und Gesang; Walzer; op. 333 – 美酒、女人和歌圆舞曲

06 – Johann Strauss II – Perpetuum mobile; Polka; op. 257 – 无穷动波尔卡

07 – Otto Nicolai – Die lustigen Weiber von Windsor; Ouvertüre – 愉快的温沙妇人序曲

08 – Johann Strauss II – Wiener Bonbons; Walzer; op. 307 – 维也纳糖果圆舞曲

09 – Hans Christian Lumbye – Champagner Galopp – 香槟加洛普

10 – Johann Strauss II – Ein Herz, ein Sinn; Polka Mazur; op. 323 – 一心一意玛祖卡波尔卡

11 – Johann Strauss I – Der Karneval in Paris; op. 100 – 巴黎狂欢节加洛普

12 – Jacques Offenbach – Ouvertüre zu “Die Feen vom Rhein” – 歌剧《莱茵河的仙女》序曲

13 – Eduard Strauss – “Die schöne Helena”; Quadrille; op. 14 – 根据轻歌剧《美丽的海伦》改编的四对舞舞曲

14 – Johann Strauss II – Morgenblätter; Walzer; op. 279 – 晨报圆舞曲

15 – Johann Strauss II – Champagner-Polka; op. 211 – 香槟波尔卡

16 – Johann Strauss II – An der schönen blauen Donau; Walzer; op. 314 – 蓝色多瑙河圆舞曲

17 – Johann Strauss I – Radetzky-Marsch; op. 228 – 拉德茨基进行曲

指挥2010年维也纳新年音乐会的是86岁的法国指挥乔治·普列特 (Georges Prêtre),他曾经在两年前执棒2008年维也纳新年音乐会。在那一届音乐会上,加演曲目《运动快速波尔卡》中,普列特拿出了足球比赛中使用的黄牌与首席小提琴开起了玩笑。乐曲结束,首席小提琴终于“忍无可忍”,从口袋中掏出红牌,把指挥罚下了指挥台。这可以算是指挥和维也纳爱乐乐团给2008年在奥地利举行的欧州杯足球赛做了一个出色的广告。

2010年的演出曲目中选择了不少经典的曲目,比如开场曲蝙蝠序曲就曾经在1980,1987,1989,1999,2002等年份多次演出,无穷动波尔卡也是一首很有特色的经典曲目。期待新一年的新年音乐会给这些经典的曲目带来新的演绎。

跟往年一样,每年的新年音乐会也会引入一些从来没有新年音乐会上演出过的曲目。2010年新年音乐会一共有4首新的曲目,在曲目单中以*标识。第一首是丹麦作曲家Lumbye的香槟加洛普,2010是Lumbye的200年诞辰纪念,Lumbye是一位擅长写作圆舞曲、波尔卡、马祖卡和加洛普的音乐家。香槟加洛普以打开香槟酒瓶的声音作为乐曲的开头,是他最著名的作品之一。这首香槟加洛普将与后面的香槟波尔卡遥相呼引,成为这个曲目单一个小小的悬念,为什么会在一场音乐会中选择两首与香槟有关的乐曲呢?奥芬巴赫的歌剧序曲也是常常入选新年音乐会的非施特劳斯家族的乐曲,这次选择的是他的歌剧《莱茵河的仙女》的序曲。爱德华的四对舞舞曲既是本次新年音乐会上的一个新曲,也是曲目单中唯一的一首他的作品。

曲目单上出现了不少的序曲,但除了结尾的拉德茨基进行曲以外,居然没有别的进行曲出现,导致了不少乐迷的质疑,有此人甚至用“乱七八糟”来表述这次的曲目安排。不过对我来说,维也纳新年音乐会这场传统的音乐盛宴很多时候已经成了一种期待、一个符号,关注的是她带给我的新的一年的气息和感受,每一年,只有欣赏过了维也纳新年音乐会,才真正体会到了新年的到来,春天的临近。

如果没有意外,2010的维也纳新年音乐会仍将由中央电视台音乐频道在元旦的晚上的18:00进行直播。这年头,数字电视和音乐频道的普及率比3年前已经高了很多,相信大部分乐迷都不会再次为收不到音乐频道而苦恼了。一直担任新年音乐会解说的“赵老师”今年故事多多,不知道是不是还会继续成为2010年新年音乐会的解说,这么多年,还真是已经习惯了他的解说风格。

2010年的唱片应该继续由Decca出版,不过目前为止还没有看到CD的封面长成什么样子,如果有看到的朋友,希望能共享一下。

下面开始跑题……

今天Mp3tag软件发布了2.45版本。Mp3tag是一个用于整理、修改、获取音乐文件的Tag信息软件。这个软件相对于刚开始用的人来说可能不是非常好用,但是一旦会用了,就会非常的高效,而且它的功能也非常强大,甚至支持写简单的脚本来控制软件的工作。推荐给拥有大量音乐文件需要管理的朋友。不过如果你觉得iTunes或Windows Media Player的音乐库管理已经足够好用,可以无视本软件。这个软件的中文汉化界面是由我在维护,如果发现软件界面翻译有问题,欢迎指正。

Mp3tag 2.45的下载网址:http://download.mp3tag.de/mp3tagv245setup.exe

生活在Linux中

昨天被一个小问题折腾了很久很久,决定把它记下来。

原本用的好好的Debian GNU/Linux 5 (Lenny),在经历了以下操作后出现了问题:更新了一下系统;安装配置了NetworkManager;把内核从2.6.31.5升级到2.6.31.6(同时把内核选项中的CPU类型由686改成CORE2); 把ATI显卡驱动从9.10升级到9.11。出现的问题是:重启或注销GNOME时系统失去响应;Firefox在链接上点右键,菜单弹出前软件失去响应。

为了排除这两个问题,做了很多的努力:Google寻找解决方案;把内核恢复到老版本;把CPU类型恢复成686重新编译内核;降级显卡驱动;重新配置Xorg.conf;以上几种方案的各种组合……均无果而终。(重点怀疑显卡驱动的原因是ATI的fglrx驱动在新内核中总是会触发一些oops)

山穷水尽之际,决定用strace看看Firefox在弹出菜单时到底在做什么事,为什么会卡住。

connect(88, {sa_family=AF_INET, sin_port=htons(16001),
sin_addr=inet_addr("127.0.0.1")}, 16...

127.0.0.1……我自己ping了一下这个本机回环地址,Request timed out。啊……

原来,这次安装了NetworkManager后发现它不工作,查了一下才知道只要是在/etc/network/interfaces中有配置的网卡都不会被NetworkManager管理,于是不管三七二十一把interfaces这个配置文件给清空了。遗憾的是原本在interfaces配置文件中配置的Loop Back网卡lo不会被NetworkManger管理的,于是127.0.0.1这个地址就不通了。

这个故事也告诉我们,lo网卡在Linux中非常重要。

1999年第一次安装Linux,2006年参加工作开始试图把Linux作为日常的操作系统,到目前为止,却还是没有办法完全离开Windows。不过对于Linux的看法早就已经从欣喜的发现“Linux也能做这件事”演变成了“遗憾,Linux还做不了这件事”,或者,更确切的说“遗憾,Linux还不能兼容这个东西”。毕竟,外面的世界还不是这么美好。Linux自身做为桌面系统来说,也还有不少的路要走。

昨天Google开会正式介绍了深度整合Linux和浏览器的操作系统Chrome OS,大概在一年多前在参加UCDChina书友会时,大家就曾经聊到过浏览器是不是可能变成操作系统,在来看来,这个理想已经更接近现实了。第一时间下载了Chrome OS镜像在VMware上体验。不过实话说,现在所看到的Chrome OS并没有给人特别惊喜,几乎纯粹Web OS的概念很领先,但就目前来看似乎并不具备足够的吸引力,毕竟现在Web还没有能力提供足够丰富和复杂的应用。更不提那众所周之原因所导致的Chrome OS的桌面无法打开,一些应用无法正常访问了。

跑题了……