項目越來越大,每次需要重新
編譯整個項目都是一件很浪費(fèi)時間的事情。Research了一下,找到以下可以幫助提高速度的方法,總結(jié)一下。
tmpfs
有人說在Windows下用了RAMDisk把一個項目編譯時間從4.5小時減少到了5分鐘,也許這個數(shù)字是有點(diǎn)夸張了,不過粗想想,把文件放到內(nèi)存上做編譯應(yīng)該是比在磁盤上快多了吧,尤其如果編譯器需要生成很多臨時文件的話。
這個做法的實現(xiàn)成本最低,在Linux中,直接mount一個tmpfs就可以了。而且對所編譯的工程沒有任何要求,也不用改動編譯環(huán)境。
mount -t tmpfs tmpfs ~/build -o size=1G
用2.6.32.2的Linux Kernel來測試一下編譯速度:
用物理磁盤:40分16秒
用tmpfs:39分56秒
呃……沒什么變化??磥砭幾g慢很大程度上瓶頸并不在IO上面。但對于一個實際項目來說,編譯過程中可能還會有打包等IO密集的操作,所以只要可能,用tmpfs是有益無害的。當(dāng)然對于大項目來說,你需要有足夠的內(nèi)存才能負(fù)擔(dān)得起這個tmpfs的開銷。
make -j
既然IO不是瓶頸,那CPU就應(yīng)該是一個影響編譯速度的重要因素了。
用make -j帶一個參數(shù),可以把項目在進(jìn)行并行編譯,比如在一臺雙核的機(jī)器上,完全可以用make -j4,讓make最多允許4個編譯命令同時執(zhí)行,這樣可以更有效的利用CPU資源。
還是用Kernel來測試:
用make: 40分16秒
用make -j4:23分16秒
用make -j8:22分59秒
由此看來,在多核CPU上,適當(dāng)?shù)倪M(jìn)行并行編譯還是可以明顯提高編譯速度的。但并行的任務(wù)不宜太多,一般是以CPU的核心數(shù)目的兩倍為宜。
不過這個方案不是完全沒有cost的,如果項目的Makefile不規(guī)范,沒有正確的設(shè)置好依賴關(guān)系,并行編譯的結(jié)果就是編譯不能正常進(jìn)行。如果依賴關(guān)系設(shè)置過于保守,則可能本身編譯的可并行度就下降了,也不能取得最佳的效果。
ccache
ccache用于把編譯的中間結(jié)果進(jìn)行緩存,以便在再次編譯的時候可以節(jié)省時間。這對于玩Kernel來說實在是再好不過了,因為經(jīng)常需要修改一些Kernel的代碼,然后再重新編譯,而這兩次編譯大部分東西可能都沒有發(fā)生變化。對于平時開發(fā)項目來說,也是一樣。為什么不是直接用make所支持的增量編譯呢?還是因為現(xiàn)實中,因為Makefile的不規(guī)范,很可能這種“聰明”的方案根本不能正常工作,只有每次make clean再make才行。
安裝完ccache后,可以在/usr/local/bin下建立gcc,g++,c++,cc的symbolic link,鏈到/usr/bin/ccache上。總之確認(rèn)系統(tǒng)在調(diào)用gcc等命令時會調(diào)用到ccache就可以了(通常情況下/usr/local /bin會在PATH中排在/usr/bin前面)。
繼續(xù)測試:
用ccache的第一次編譯(make -j4):23分38秒
用ccache的第二次編譯(make -j4):8分48秒
用ccache的第三次編譯(修改若干配置,make -j4):23分48秒
看來修改配置(我改了CPU類型...)對ccache的影響是很大的,因為基本頭文件發(fā)生變化后,就導(dǎo)致所有緩存數(shù)據(jù)都無效了,必須重頭來做。但如果只是修改一些.c文件的代碼,ccache的效果還是相當(dāng)明顯的。而且使用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
一臺機(jī)器的能力有限,可以聯(lián)合多臺電腦一起來編譯。這在公司的日常開發(fā)中也是可行的,因為可能每個開發(fā)人員都有自己的開發(fā)編譯環(huán)境,它們的編譯器版本一般是一致的,公司的網(wǎng)絡(luò)也通常具有較好的性能。這時就是distcc大顯身手的時候了。
使用distcc,并不像想象中那樣要求每臺電腦都具有完全一致的環(huán)境,它只要求源代碼可以用make -j并行編譯,并且參與分布式編譯的電腦系統(tǒng)中具有相同的編譯器。因為它的原理只是把預(yù)處理好的源文件分發(fā)到多臺計算機(jī)上,預(yù)處理、編譯后的目標(biāo)文件的鏈接和其它除編譯以外的工作仍然是在發(fā)起編譯的主控電腦上完成,所以只要求發(fā)起編譯的那臺機(jī)器具備一套完整的編譯環(huán)境就可以了。
distcc安裝后,可以啟動一下它的服務(wù):
/usr/bin/distccd --daemon --allow 10.64.0.0/16
默認(rèn)的3632端口允許來自同一個網(wǎng)絡(luò)的distcc連接。
然后設(shè)置一下DISTCC_HOSTS環(huán)境變量,設(shè)置可以參與編譯的機(jī)器列表。通常localhost也參與編譯,但如果可以參與編譯的機(jī)器很多,則可以把localhost從這個列表中去掉,這樣本機(jī)就完全只是進(jìn)行預(yù)處理、分發(fā)和鏈接了,編譯都在別的機(jī)器上完成。因為機(jī)器很多時,localhost的處理負(fù)擔(dān)很重,所以它就不再“兼職”編譯了。
export DISTCC_HOSTS="localhost 10.64.25.1 10.64.25.2 10.64.25.3"
然后與ccache類似把g++,gcc等常用的命令鏈接到/usr/bin/distcc上就可以了。
在make的時候,也必須用-j參數(shù),一般是參數(shù)可以用所有參用編譯的計算機(jī)CPU內(nèi)核總數(shù)的兩倍做為并行的任務(wù)數(shù)。
同樣測試一下:
一臺雙核計算機(jī),make -j4:23分16秒
兩臺雙核計算機(jī),make -j4:16分40秒
兩臺雙核計算機(jī),make -j8:15分49秒
跟最開始用一臺雙核時的23分鐘相比,還是快了不少的。如果有更多的計算機(jī)加入,也可以得到更好的效果。
在編譯過程中可以用distccmon-text來查看編譯任務(wù)的分配情況。distcc也可以與ccache同時使用,通過設(shè)置一個環(huán)境變量就可以做到,非常方便。
總結(jié)一下:
tmpfs: 解決IO瓶頸,充分利用本機(jī)內(nèi)存資源
make -j: 充分利用本機(jī)計算資源
distcc: 利用多臺計算機(jī)資源
ccache: 減少重復(fù)編譯相同代碼的時間
這些工具的好處都在于布署的成本相對較低,綜合利用這些工具,就可以輕輕松松的節(jié)省相當(dāng)可觀的時間。上面介紹的都是這些工具最基本的用法,更多的用法可以參考它們各自的man page。
posted on 2012-02-09 13:45
李陽 閱讀(580)
評論(0) 編輯 收藏 引用 所屬分類:
Linux