Linux編譯命令——make -j8 提升編譯速度

項目越來越大,每次需要重新編譯整個項目都是一件很浪費時間的事情。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不規範,沒有正確的設置好依賴關係,並行編譯的結果就是編譯不能正常進行。如果依賴關係設置過於保守,則可能本身編譯的可並行度就下降了,也不能取得最佳的效果。

超線程技術的原理很簡單,以前的單核心處理器,在同一時間內只可以處理一項工作 (線程,Thread),如果要處理一項以上的工作時,以前的單核心處理器是不可行的,所以英特爾就開發了超線程技術,以一個單核心的處理器,去模擬出雙核心的環境,但這並非能夠把處理器的效能提升雙倍,原因在於實體的核心始終只有一個,而效能有約百分之至二十至三十增長。

在奔騰四時代INTEL就已經引入了人超線程技術,而特意的加長的流水線反而成了HT技術的累贅。

所以推出奔騰D及後來的酷睿2系列時,英特爾並沒有加進超線程技術,因爲奔騰D及酷睿2處理器已支援雙核心處理器的運作,而且INTEL也在默默的鑽研指令預測技術減少流水線。在酷睿2後期英特爾推出了酷睿2四核心處理器,因爲有用戶反映雙核不足以應付手頭的工作,再到後來, 英特爾酷睿i7出現了,他帶着 Intel 全新的超線程技術,很短的流水線這得益於他的指令分支預測技術,擁有着奔騰四無法企及的效率,它是四核心處理器加進了超線程技術,處理器同時支持處理八個線程的工作,在這種環境下電腦可掛很多應用程序,支持多線程的應用,因此即使N多程序同時運行,電腦也沒有運行減慢的感覺,操作起來依然是流暢如行雲流水。

其實超線程技術擁有最高的功耗效能比,加入超線程技術所增加的晶體管數目及功耗並不多,但卻相比增加一顆完整的核心更具性價比,加上酷睿i7微架構擁有高帶寬及高容量三級高速緩存的優勢,更能將超線程技術的功效發揮到極致。

要打開超線程技術,很簡單,一般而言,在BIOS內就可以設定超線程技術的啓動與否。當設定完成後,進入Windows的“我的電腦”,查看處理器,就能看出八個線程的工作情況。

加入超線程技術的英特爾酷睿i7處理器在多任務應用時最能發揮它的潛能,它可以同時處理N個的遊戲及多媒體軟件,而不會出現慢式死機。有人做了一些評測,是用Cinebench 10,跑Far Cry 2 及Company of Heroes來測試有打開超線程技術與沒有開啓的性能的區別。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章