icecream / icecc:分散式編譯系統簡介
TRANSCRIPT
2
自我介紹
安第斯山脈Compiler Team專業打雜工
3
這份簡報包含 ...
• icecc 安裝與環境的架設•如何使用 icecc 進行 cross-compilation•使用心得跟一些實驗數據• icecc 運作原理與內部設計•與 distcc 的比較
4
icecc 是什麼?
•分散式的編譯系統– 有效利用多台機器加速編譯速度
5
icecc 是什麼?
•分散式的編譯系統– 有效利用多台機器加速編譯速度
•不是一個編譯器– 由 distcc fork 而成
•目前兩邊差異已經相當大– 需要 GCC 或 LLVM
•官方僅支援這兩種編譯器
6
distcc 錯惹嗎 ?
7
distcc 錯惹嗎 ?
• 最單純的情況下只要設定 DISTCC_HOSTS• 若要 cross-compilation 整個就是悲劇 ...• 如果 server 群的環境不太一樣的話也很容易發生悲劇
• 最後會介紹 distcc 的部份運作機制與 icecc 比較
8
安裝
• Debian/Ubuntu– $ sudo apt-get install icecream
• Fedora– $ sudo dnf install icecream
• CentOS– $ sudo yum install icecream
9
Server side
• icecc 中 server 分兩種– icecc-scheduler
•網路環境中只需要一個即可•負責分配工作
– iceccd•每台 Server 都需要執行 iceccd•負責處理工作
10
Server side / scheduler
• Ubuntu/CentOS– service icecc-scheduler start
• Fedora– systemctl start icecc-scheduler.service
11
Server side / iceccd
• Ubuntu/CentOS– service iceccd start
• Fedora– systemctl start iceccd
12
Zero config
• 正常情況下設定完全不用修改即可運作
• iceccd 打起來就會主動搜索有無 icecc-scheduler 並且自動加入
13
icecc 設定
• 其實也是有可以設定的東西啦 ... 不過通常都不用改就會動啦 ~
• ICECREAM_NETNAME– 這台機器的名稱 , 預設值是 hostname
• ICECREAM_SCHEDULER_HOST– 指定要使用哪個 Scheduler server, 不設定的話 iceccd
會自己去找區網上的其中一個
• ICECREAM_ALLOW_REMOTE– 是否允許其他機器利用本機端來編譯 , 預設值通常是 yes
• ICECREAM_MAX_JOBS– 這台機器最多負載的編譯工作數目 , 預設值會根據該機器
上的處理器數量來決定
14
基礎用法
•就像使用 distcc 或 ccache 一樣
• icecc <compiler> ...
• icecc gcc foo.c -c -O
15
便利的用法
•用個 wrapper– ln -s /usr/bin/icecc gcc– ln -s /usr/bin/icecc g++– ln -s /usr/bin/icecc cc– ln -s /usr/bin/icecc clang– ln -s /usr/bin/icecc clang++
16
系統附贈的 icecc wrapper
• Fedora– /usr/libexec/icecc/bin/gcc– /usr/libexec/icecc/bin/g++
• Ubuntu– /usr/lib/icecc/bin/gcc– /usr/lib/icecc/bin/g++
17
實驗環境
• 硬體環境– CPU : E3-1230 v3 @ 3.30GHz (8 logic core) * 4– RAM : 32GB– Network : 1 Gigabit Ethernet
• 軟體環境– OS : Fedora 22 / Gentoo
•系統內建 GCC 版本 : 5.3 / 5.2 / 4.9.2– ICECC version : 1.0.90– GCC : 4.9.3
• ICECREAM 組態– ICECREAM_MAX_JOBS=12
18
實驗對象• LLVM Version: r26441•編譯 LLVM Debug build
– Configure as :• -DCMAKE_BUILD_TYPE=Debug -DLLVM_OPTIMIZED_TABLEGEN=ON
•編譯 LLVM Release build– Configure as :
• -DCMAKE_BUILD_TYPE=Release
•平行與分散 :– time make -j48– time make -j12
19
實驗數據
LLVMBuild Type
icecc gcc Speed up Total file size
for build folder
ReleaseBuild
2m57.275s 10m34.657s 3.6x 919M
DebugBuild
5m10.249s 12m2.120s 2.3x 12G
20
實驗數據分析
• Release build 加速與極限值 4 倍相差不遠– Link 階段無法平行化
• Release build 比 Debug build 還慢?–輸出結果要透過網路傳輸– 900M vs 12G
21
實驗環境 2• 硬體環境
– CPU :• E3-1230 v3 @ 3.30GHz (8 logic core) * 5• E3-1230 v2 @ 3.30GHz (8 logic core) * 1
– RAM : 32GB– Network : 1 Gigabit Ethernet + 100 Megabit Ethernet
• 軟體環境– OS : Fedora 22 / Gentoo / CentOS 6
•系統內建 GCC 版本 : 5.3 / 5.2 / 4.9.2 / 4.4.7– ICECC version : 1.0.90– GCC : 5.3 (Fedora 22 內建 )
• ICECREAM 組態– ICECREAM_MAX_JOBS=12
22
實驗數據 2
LLVMBuild Type
icecc gcc Speed up Total file size
for build folder
ReleaseBuild
1m55.630s 10m34.657s 5.5x 919M
23
試過用 icecc建置的 Project
• GCC/Binutils/Glibc/GDB– Cross-compilation and Native
• Linux Kernel– Cross-compilation
24ICECC 運作原理
25
運作原理
•呼叫 gcc/clang 進行 pre-process•將工作丟到 iceccd• iceccd 向 icecc-scheduler 找一台閒置的機器
•丟 pre-process 過後的檔案到遠端進行編譯
•接收遠端的編譯結果
26
icecc 的假設
•在任意一台機器上同樣的 input 配上同樣的 options 會輸出同樣的 output– Input: source code– Ouput: object code
27
任意一台機器 ?
• icecc 支援的平台 :– Linux– FreeBSD– DragonFlyBSD– OS X
•支援不同架構–例如 x86_64/x86/arm/ppc/s390
Note: 只試過 x86_64 + x86 Linux 上 , 沒試過混搭 OS/Arch 的環境
28
不同架構間的相容性
•相容列表 :– i*86/x86_64– ppc/ppc64– s390/s390x
•例如 i686 的 executable 可以直接在 x86_64 上跑
29
假設一定會成立嗎 ?
•有些 Option 在不同機器上會有不同效果– -mtune=native– -march=native– -mcpu=native
•遇到這些 Option 就會強制 local build
30
還有其它限制嗎?
•目前 icecc 無法處理多個 Output file– -save-temps– -fprofile-arcs– -fbranch-probabilities– -fprofile-use– -fprofile-generate– ...
•遇到這類 Option 也會強制 local build
31
gcc 版本不一樣怎麼辦?
• icecc 在設計上就有考慮到這個問題
•接著會介紹遠端接收到工作如何處理
32
icecc 運作原理 /收到遠端工作
•接收工作•確認該工作使用的編譯環境是否本地端有沒有– 沒有的話就跟工作來源的機器要
•準備編譯環境•進行編譯•傳回編譯結果
33
icecc 編譯環境
• iceccd 啟動時會自動建立– 預設找系統的 gcc/g++
•透過 ICECC_VERSION 環境變數設定– 使用 icecc-create-env– 若使用系統的 gcc/g++ 可不指定
34
使用 icecc-create-env建置編譯環境
$ icecc-create-env --gcc /usr/bin/gcc /usr/bin/g++$ icecc-create-env --clang /usr/bin/clang
$ icecc-create-env --gcc <path-to-gcc> <path-to-g++>$ icecc-create-env --clang <path-to-clang>$ icecc --build-native
例如
35
使用 icecc-create-env建置編譯環境
$ icecc-create-env --gcc /usr/bin/gcc /usr/bin/g++adding file /bin/trueadding file /lib64/libc.so.6adding file /lib64/ld-linux-x86-64.so.2adding file /usr/bin/gccadding file /lib64/libm.so.6adding file /usr/bin/g++adding file /usr/bin/cc1=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/cc1adding file /lib64/libdl.so.2adding file /lib64/libmpc.so.3adding file /lib64/libmpfr.so.4adding file /lib64/libgmp.so.10adding file /lib64/libz.so.1adding file /usr/bin/cc1plus=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/cc1plusadding file /usr/bin/asadding file /lib64/libopcodes-2.25-15.fc23.soadding file /lib64/libbfd-2.25-15.fc23.soadding file /usr/libexec/gcc/x86_64-redhat-linux/5.3.1/liblto_plugin.soadding file /etc/ld.so.conf=/tmp/icecc_ld_so_confTVPvU7cp: omitting directory ‘/lib’cp: omitting directory ‘/lib64’creating 873f2d89faf900aa39d8a5673521d0df.tar.gz
36
編譯環境的內容物$ tar -tvf 873f2d89faf900aa39d8a5673521d0df.tar.gz-rwxr-xr-x 1000/1000 28432 2016-03-22 21:53 bin/true-rw-r--r-- 1000/1000 794 2016-03-22 21:53 etc/ld.so.cache-rw------- 1000/1000 33 2016-03-22 21:53 etc/ld.so.conf-rwxr-xr-x 1000/1000 142472 2016-03-22 21:53 lib64/ld-linux-x86-64.so.2-rwxr-xr-x 1000/1000 1205936 2016-03-22 21:53 lib64/libbfd-2.25-15.fc23.so-rwxr-xr-x 1000/1000 1833648 2016-03-22 21:53 lib64/libc.so.6-rwxr-xr-x 1000/1000 15152 2016-03-22 21:53 lib64/libdl.so.2-rwxr-xr-x 1000/1000 494096 2016-03-22 21:53 lib64/libgmp.so.10-rwxr-xr-x 1000/1000 101208 2016-03-22 21:53 lib64/libmpc.so.3-rwxr-xr-x 1000/1000 396680 2016-03-22 21:53 lib64/libmpfr.so.4-rwxr-xr-x 1000/1000 1060920 2016-03-22 21:53 lib64/libm.so.6-rwxr-xr-x 1000/1000 1600312 2016-03-22 21:53 lib64/libopcodes-2.25-15.fc23.so-rwxr-xr-x 1000/1000 89472 2016-03-22 21:53 lib64/libz.so.1-rwxr-xr-x 1000/1000 392984 2016-03-22 21:53 usr/bin/as-rwxr-xr-x 1000/1000 21152336 2016-03-22 21:53 usr/bin/cc1-rwxr-xr-x 1000/1000 22749840 2016-03-22 21:53 usr/bin/cc1plus-rwxr-xr-x 1000/1000 919856 2016-03-22 21:53 usr/bin/g++-rwxr-xr-x 1000/1000 915744 2016-03-22 21:53 usr/bin/gcc-rwxr-xr-x 1000/1000 68344 2016-03-22 21:53 usr/libexec/gcc/x86_64-redhat-linux/5.3.1/liblto_plugin.so
37
編譯環境解析•編譯器的執行檔
– gcc/g++/cc1/cc1plus•組譯器的執行檔
– as•所有相關的 Shared library
– libc.so, libm.so ...• Dynamic Linker
– ld.so, /etc/ld.so.conf• /bin/true
– 用來快速確保該機器是否可執行此編譯環境
38
Cross Compilation
•使用 icecc-create-env 來建立編譯環境–例如要使用 aarch64 gcc
$ icecc-create-env --gcc \ bin/aarch64-linux-gnu-gcc \ bin/aarch64-linux-gnu-g++…creating 5a1f48aacc455db5ff0d0104a827651c.tar.gz
39
Cross Compilation
$ export ICECC_VERSION=5a1f48aacc455db5ff0d0104a827651c.tar.gz$ export ICECC_CC=<path-to-aarch64-linux-gnu-gcc>$ export ICECC_CXX=<path-to-aarch64-linux-gnu-g++>$ icecc aarch64-linux-gnu-gcc hello.c -c -O
40
Cross Compilationwith wrapper
#! /usr/bin/env bashexport ICECC_VERSION=5a1f48aacc455db5ff0d0104a827651c.tar.gzexport ICECC_CC=<path-to-aarch64-linux-gnu-gcc>export ICECC_CXX=<path-to-aarch64-linux-gnu-g++>
icecc aarch64-linux-gnu-gcc "$@"
41
icecc-scheduler
•中控式•避免分配工作到 loading 重的 server•優先分配工作到比較快的 server
42
icecc-scheduler
•中控式•避免分配工作到 loading 重的 server•優先分配工作到比較快的 server
•有時候會看到都不在自己機器上 compile 的情況 ...XD
43
icemon
• icecc 的監控軟體
44DISTCC 運作原理
45
distcc 運作原理 /收到遠端工作
•接收工作•進行編譯•傳回編譯結果
46
distcc 設定
• 設定 DISTCC_HOSTS 或著是 /etc/distcc/hosts– 每個 client 都要設定
47
distcc 常見問題
•當遠端機器上面的 gcc 與本地端版本不符的時候 ...–不同機器編譯出來的 Output 則可能會不一樣•編譯結果變得無法預期並且每次可能不同
Using different versions of gcc can cause confusing build problems because the header files and binary interfaces have changed over time, and some distributors have included incompatible patches without changing the version number. distcc does not protect against using incompatible versions. Compiler errors about link problems or declarations in system header files are usually due to mismatched or incorrectly installed compilers.
摘錄自 distcc man page
48
Cross Compilation for distcc
•ㄎㄎㄎ
49
Cross Compilation for distcc
•ㄎㄎㄎThe recommended convention for the gcc name is TARGET-gcc-VERSION such as i686-linux-gcc-3.2. GCC 3.3 will install itself under this name, in addition to TARGET-gcc and, if it's native, gcc-VERSION and gcc.
The compiler must be installed under the same name on the client and on every volunteer machine.
摘錄自 distcc man page
50
Cross Compilation for distcc
•ㄎㄎㄎ
•簡單說就是要使用者自己在每台機器上裝好 Cross Compiler 啦~
The recommended convention for the gcc name is TARGET-gcc-VERSION such as i686-linux-gcc-3.2. GCC 3.3 will install itself under this name, in addition to TARGET-gcc and, if it's native, gcc-VERSION and gcc.
The compiler must be installed under the same name on the client and on every volunteer machine.
摘錄自 distcc man page
51
Merge back to distcc?
• distcc maintainer 跑到 icecc 那邊問要不要 Merge 回來阿~?
https://github.com/icecc/icecream/issues/138
52
Merge back to distcc?
• distcc maintainer 跑到 icecc 那邊問要不要 Merge 回來阿~?
• icecc 表示 : 之前的 pull request 都放半年以上沒人鳥現在還有臉說要 merge?
https://github.com/icecc/icecream/issues/138
53
Merge back to distcc?
• distcc maintainer 跑到 icecc 那邊問要不要 Merge 回來阿~?
• icecc 表示 : 之前的 pull request 都放半年以上沒人鳥現在還有臉說要 merge?
•而且兩邊架構已經差太多啦~~~
https://github.com/icecc/icecream/issues/138