硬體部分是4塊Raspberry Pi Model B+板子,記憶卡皆是SanDisk Ultra Micro SD 8GB,電源部分採用anidees的產品5 Port USB Charger 25W,然後使用乙太網路線連接到ZyXEL的GS-108B(8埠桌上型超高速乙太網路交換器),這台交換器再接到Wi-Fi無線路由器,連上網路。
左邊乙太網路交換器,中間4塊rpi板子,右邊電源供應器。
$ sudo apt-get update; sudo apt-get dist-upgrade -y
distcc可把C/C++/Objective-C程式的編譯工作,分散到網路上的別台機器。distcc本身不是編譯器,而是編譯器的前端介面,預設行為是把前置處理完畢的原始程式檔,傳送到給另一台機器進行編譯,因此另一台機器需要安裝適當的編譯器,並且執行distccd,接收編譯要求。
底下皆以gcc為範例,Raspbian預設已安裝:
$ gcc --version
gcc (Raspbian 4.9.2-10) 4.9.2
首先安裝distcc套件,每一台機器都要安裝:
$ 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 Nov 7 2014 11:06:15
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.
distcc comes with ABSOLUTELY NO WARRANTY. distcc is free software, and
you may use, modify and redistribute it under the terms of the GNU
General Public License version 2 or later.
Built with Zeroconf support.
Please report bugs to distcc@lists.samba.org
底下先以手動方式進行,之後會記錄在組態設定檔。
首先試試一般編譯需要多少時間,以zlib這套程式庫為測試對象,下載、解壓縮、組態、開始以make建置。此處不安裝,所以不執行指令make install。
$ wget http://zlib.net/zlib-1.2.8.tar.gz
$ tar zxvf zlib-1.2.8.tar.gz
$ cd zlib-1.2.8
$ ./configure
$ time make test
結果如下:
...省略...
zlib version 1.2.8 = 0x1280, compile flags = 0x55
uncompress(): hello, hello!
gzread(): hello, hello!
gzgets() after gzseek: hello!
inflate(): hello, hello!
large_inflate(): OK
after inflateSync(): hello, hello!
inflate with dictionary: hello, hello!
*** zlib 64-bit test OK ***
real 2m4.111s
user 1m59.470s
sys 0m2.780s
嗯,花了2分4秒。接下來試試分散編譯,先刪除之前的東西,重新解壓縮,這樣比較準。
以底下指令設定欲接受分散編譯要求的機器,我的每台機器(4塊rpi板子)皆位於同一區域網路內,網址是192.168.1.x,所以如下設定:
$ distccd --daemon --allow 127.0.0.1 --allow 192.168.1.0/24
distccd扮演伺服器的角色,負責接收distcc傳來的編譯要求,以--allow設定可傳進編譯要求的機器。
我把4塊板子的主機名稱(hostname)分別設為rpi_p1、rpi_p2、rpi_p3、rpi_p4。如下以環境變數設定要把編譯要求丟到哪些機器上:
rpi_p1增加環境變數,
$ export DISTCC_HOSTS="rpi_p2 rpi_p3 rpi_p4 localhost"
rpi_p2增加環境變數,
$ export DISTCC_HOSTS="rpi_p3 rpi_p4 rpi_p1 localhost"
rpi_p3增加環境變數,
$ export DISTCC_HOSTS="rpi_p4 rpi_p1 rpi_p2 localhost"
rpi_p4增加環境變數,
$ export DISTCC_HOSTS="rpi_p1 rpi_p2 rpi_p3 localhost"
代表distcc可傳送編譯要求的機器。
然後開始建置zlib,指令如前,但要加上CC=distcc。
$ time make test CC=distcc
咦,居然花了2分8秒,比以前還慢啊!因為指令下錯了,還需要加上-j,因為我有四台機器,所以先試試-j4,
$ time make test -j4 CC=distcc
花了43秒,比之所花時間(2分4秒)的四分之一(31秒)還要多,額外的時間花在分散工作、傳輸等等。我試著改成-j8,花費39秒。
嗯,很不錯,讓我們試著新增或修改組態設定檔吧,不必每次自己手動輸入指令,其實就是把之前的東西寫入檔案,如此而已。首先修改/etc/default/distcc,應含如下內容(其餘東西不變):
STARTDISTCC="true"
ALLOWEDNETS="127.0.0.1 192.168.1.0/24"
LISTENER="0.0.0.0"
STARTDISTCC設為"true"代表開機時會自動執行distccd;ALLOWEDNETS則設定允許哪些機器可傳入編譯要求;LISTENER則代表要聆聽哪個網路介面,"0.0.0.0"代表全部。
接下來是修改/etc/distcc/hosts,此檔是給整台機器用的;若個人帳號有不同設定,則是放在~/.distcc/hosts裡:
rpi_p1的內容:
rpi_p2 rpi_p3 rpi_p4 localhost
rpi_p2的內容:
rpi_p3 rpi_p4 rpi_p1 localhost
rpi_p3的內容:
rpi_p4 rpi_p1 rpi_p2 localhost
rpi_p4的內容:
rpi_p1 rpi_p2 rpi_p3 localhost
搞定,然後重開機,便能以之前介紹的make指令進行編譯。
3.0版的distcc開始支援pump模式,除了編譯工作、也把前置處理工作分散到別台機器,因此別台機器須擁有相同的系統標頭檔,至於應用程式(建置對象)特有的標頭檔,仍由distcc傳輸;另外還有壓縮功能,速度應會更快。先安裝套件distcc-pump,每一台機器都要:
$ sudo apt-get install distcc-pump
rpi_p1修改環境變數,
$ export DISTCC_HOSTS="--randomize localhost rpi_p2,cpp,lzo rpi_p3,cpp,lzo rpi_p4,cpp,lzo"
rpi_p2修改環境變數,
$ export DISTCC_HOSTS="--randomize localhost rpi_p3,cpp,lzo rpi_p4,cpp,lzo rpi_p1,cpp,lzo"
rpi_p3修改環境變數,
$ export DISTCC_HOSTS="--randomize localhost rpi_p4,cpp,lzo rpi_p1,cpp,lzo rpi_p2,cpp,lzo"
rpi_p4修改環境變數,
$ export DISTCC_HOSTS="--randomize localhost rpi_p1,cpp,lzo rpi_p2,cpp,lzo rpi_p3,cpp,lzo"
其中--randomize代表先打亂接受分散編譯要求的機器,cpp代表有pump模式,lzo代表要壓縮。建置指令如下:
$ time distcc-pump make test -j4 CC=distcc
花了42秒,差不多,或許跟測試對象有關,我只有4台機器,效果不明顯吧。同樣的,也可以把此處設定放進/etc/distcc/hosts或~/.distcc/hosts。
在distcc執行時,以指令distccmon-text可得知其狀態:
$ distccmon-text
3339 Compile ngx_http_variables.c localhost[0]
3350 Preprocess localhost[2]
3343 Compile ngx_http_script.c rpi_p3[0]
3347 Compile ngx_http_upstream.c rpi_p4[0]
我又試著建置nginx(1.9.9版), 只一台機器需要8分鐘,四台機器與pump模式的話,需要4分鐘18秒。
搞定收工,用紙盒幫rpi做個家吧,很簡陋。
參考資料:
- distcc - a free distributed C/C++ compiler system - on GitHub,distcc原始碼,基本介紹。
- distcc: a fast, free distributed C/C++ compiler。
- manual page,distcc、distccd、pump。
- debian - How do I install distcc? - Raspberry Pi Stack Exchange。
- Using distcc | Linux Magazine。
- Debian Administration的Speed up compiling software with distcc。
No comments:
Post a Comment