專案越來越大,每次需要重新編譯整個專案都是一件很浪費時間的事情。research了一下,找到以下可以幫助提高速度的方法,總結一下。
有人說在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的開銷。
既然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用於把編譯的中間結果進行快取,以便在再次編譯的時候可以節省時間。這對於玩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的磁碟,還是完全可以接受的。
鏈結(link):系統中的鏈結是乙個已經存在的檔案的另乙個名字,它不複製檔案的內容。有兩種鏈結方式,一種是硬鏈結(hard link),另一種是符號鏈結(symbolic link),又稱軟鏈結。硬鏈結和原有檔案是儲存在同一實體地址的兩個不同的名字,因此硬鏈結是相互的;符號鏈結的內容只是乙個所鏈結檔案的檔名,在使用ls –l時,符號鏈結的第一項的第一位為「l」。
指向乙個檔案的所有 硬鏈結都刪掉的話檔案的內容才會被刪掉
軟鏈結只要刪掉了源鏈結檔案,軟鏈結也就失效了
一台機器的能力有限,可以聯合多台電腦一起來編譯。這在公司的日常開發中也是可行的,因為可能每個開發人員都有自己的開發編譯環境,它們的編譯器版本一般是一致的,公司的網路也通常具有較好的效能。這時就是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同時使用,通過設定乙個環境變數就可以做到,非常方便。
總結一下:
加速Linux程式編譯
專案越來越大,每次需要重新編譯整個專案都是一件很浪費時間的事情。research了一下,找到以下可以幫助提高速度的方法,總結一下。tmpfs 有人說在windows下用了ramdisk把乙個專案編譯時間從4.5小時減少到了5分鐘,也許這個數字是有點誇張了,不過粗想想,把檔案放到記憶體上做編譯應該是比...
加速Linux程式編譯
專案越來越大,每次需要重新編譯整個專案都是一件很浪費時間的事情。research了一下,找到以下可以幫助提高速度的方法,總結一下。有人說在windows下用了ramdisk把乙個專案編譯時間從4.5小時減少到了5分鐘,也許這個數字是有點誇張了,不過粗想想,把檔案放到記憶體上做編譯應該是比在磁碟上快多...
make的 j命令(加速Linux程式編譯)
專案越來越大,每次需要重新編譯整個專案都是一件很浪費時間的事情。research了一下,找到以下可以幫助提高速度的方法,總結一下。有人說在windows下用了ramdisk把乙個專案編譯時間從4.5小時減少到了5分鐘,也許這個數字是有點誇張了,不過粗想想,把檔案放到記憶體上做編譯應該是比在磁碟上快多...