分布式編譯以及如何加快編譯速度

2021-08-11 19:17:01 字數 4409 閱讀 8293

眾所周知,

c++專案的編譯時間一般都很就,稍微大一點的專案完全編譯可能就需要幾十分鐘,有的可能需要好幾個小時甚至更久。這對於現在的開發人員來說是非常難以忍受的一件事情!所以就有人開發了一種叫做分布式編譯的東西,這個東西的思想其實很簡單,就是把乙個專案中的沒有依賴關係的工程分給不同的機器進行同時編譯,編譯完以後把編譯出來的結果傳回來。這樣的話理論上來說,如果網路內可用的空閒機器數量足夠,編譯時間可以縮短到乙個很短的範圍內。但是不排除網路通訊上的影響因素。

當前分布式編譯的軟體有很多,比如說

xoreax

的incredibuild

,這個特點是能夠與

visual studio

很好的相容;開源的

distcc

可以提供在

linux

作業系統下的分布式編譯,其他還有很多的分布式編譯軟體都可以進行分布式編譯,它們各自有各自的優缺點。

專案越來越大,每次需要重新編譯整個專案都是一件很浪費時間的事情。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: 減少重複編譯相同**的時間

5.還有提速方法是把螢幕輸出重定向到記憶體檔案或/dev/null,因對終端裝置(慢速裝置)的阻塞寫操作也會拖慢速度。推薦記憶體檔案,這樣發生錯誤時,能夠檢視。

分布式編譯

這是乙個對應visual c 的分布式編譯軟體,通過visual c 強大的ide擴充套件功能,它有著非常友好的介面,可以將整個分布式編譯過程直觀的展現給使用者,並且它通過乙個 虛擬機器 的技術,使能編譯的參與者可以與編譯發起者有著不同的系統配置 windows作業系統版本,庫檔案等 甚至無需在參與...

加快 apk 的編譯速度

簡介 加快 apk 的編譯速度 fastdex 加快android打包速度 android studio 加快android studio編譯速度 加快apk的編譯速度 如果你忍受不了 apk 龜速的編譯 尤其是專案中有多個 dex fastdex 可以幫助你加快 apk 生成過程 版本記錄 ide...

加快Android Studio的編譯速度

從eclipse切換到android studio後,感覺android studio的build速度比eclipse慢很多,以下幾個方法可以提高android studio的編譯速度 gradle 2.4對執行效能有很大的優化,但android studio現在預設使用的是gradle 2.2,所...