2013/10/06

使用distcc加速編譯(Raspberry Pi+Raspbian)

我手上有兩塊Raspberry Pi Model B 512MB,都灌了Raspbian(2013-09-25-wheezy-raspbian.img),這篇要試試看利用distcc將編譯工作分散到兩台機器上,加快編譯速度。其中一台的記憶卡是Kingston 8G SDHC Class 10,讀寫速度大約是讀11.0 MB/s、寫19.4 MB/s,以下簡稱為K;另一台的記憶卡是SanDisk Ultra 8G SDHC Class 10,讀16.2 MB/s、寫21.7 MB/s,效能表現比較好,以下簡稱S。

灌好Raspbian後,初始設定(區域設置、鍵盤配置、等等)完成後,先更新一下套件吧:

$ sudo apt-get update; sudo apt-get dist-upgrade -y

distcc最容易搭配gcc(不意外),可編譯C/C++/Objective-C等語言,雖也可能搭配其他編譯器,但我也沒嘗試過,此篇以gcc為例,Raspbian也預設安裝gcc了:

$ gcc --version
gcc (Debian 4.6.3-14+rpi1) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

安裝distcc套件(K跟S都要安裝):

$ sudo apt-get install distcc

安裝後會有指令distcc、指令distccd、以及其他。

$ distcc --version
distcc 3.1 arm-unknown-linux-gnueabihf
  (protocols 1, 2 and 3) (default port 3632)
  built May 31 2012 22:38:08
Copyright (C) 2002, 2003, 2004 by Martin Pool.
Includes miniLZO (C) 1996-2002 by Markus Franz Xaver Johannes Oberhumer.
Portions Copyright (C) 2007-2008 Google.

版本3.1開始支援pump模式,之後會使用。

可以修改設定檔/etc/default/distcc,開機會自動執行distcc的伺服器,不過底下我都是以手動方式進行。

首先試試一般編譯時需要多少時間,以zlib這套程式庫為測試目標,抓取、解壓縮、組態、開始以make建置:

$ wget http://zlib.net/zlib-1.2.8.tar.gz
$ tar zxvf zlib-1.2.8.tar.gz
$ cd zlib-1.2.8
$ ./configure
$ make test

至於指令make install是安裝,在此不需要。另外,應把指令make test換成time make test,才能得知花了多少時間,結果如下:

gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o example.o test/example.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o adler32.o adler32.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o crc32.o crc32.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o deflate.o deflate.c
gcc -O3  -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN   -c -o infback.o infback.c
...省略...
real    2m35.417s
user    2m13.890s
sys     0m4.140s

嗯,K花了2分鐘35秒,而S花了2分鐘10秒。

接下來試試分散編譯,先把先前的zlib通通殺掉,重新解壓縮,這樣比較準。

以底下指令設定可進行分散編譯的機器,K與S都會於區域網路內,網址是192.168.1.x,所以如下設定(K與S都要執行):

$ distccd --daemon --allow 127.0.0.1 --allow 192.168.1.0/24

distccd算是伺服器的角色,等一下會接收distcc傳來的編譯要求,以--allow設定可傳進編譯要求的機器。

K的hostname是raspberry,S的hostname是rpi。

K增加環境變數,
$ export DISTCC_HOSTS="rpi localhost"

S增加環境變數:
$ export DISTCC_HOSTS="raspberrypi localhost"

代表distcc可傳送編譯要求的機器。

然後開始建置zlib,指令如前,但要加上CC=distcc。

$ time make test CC=distcc

咦,K居然花了3分鐘,S花了2分鐘41秒,比以前還慢啊!因為指令下錯了,還需要加上-j,因為我有兩台機器,所以建議是-j4,

$ time make test -j4 CC=distcc

K居然花了1分鐘25秒,S花了1分鐘15秒,嗯,的確大概是之前的二分之一,哈哈。

3.1版的distcc開始支援pump模式,也就是將程式碼檔與標頭檔,壓縮後通通傳到另一台機器進行編譯,應該會更快才是。先安裝(K跟S都要):

$ sudo apt-get install distcc-pump

然後修改環境變數,K:
$ export DISTCC_HOSTS="--randomize localhost rpi,cpp,lzo"

S:
$ export DISTCC_HOSTS="--randomize localhost raspberrypi,cpp,lzo"

建置指令如下:

$ time distcc-pump make -j4 CC=distcc

不過測試結果並沒有快多少,或許跟測試目標有關,我只有2台機器,效果不明顯吧。


參考資料:

No comments:

Post a Comment