級別: 初級 |
Linux consultant, IBM
2005 年 7 月 04 日
要將 Linux™ C/C++ 程序從 x86 平臺(Intel® 或 AMD)移植到 Linux on POWER™ 上,可以使用下面介紹的這些詳細步驟。首先,我們來了解要為這種移植準備哪些內容;然后再遵循本文介紹的實現技巧就可以將您的 x86 平臺的 Linux 上運行的代碼移植到 POWER 平臺上。
簡介
通常,將 Linux 程序從 x86 平臺移植到 Linux on POWER 上的過程非常簡單,因為這兩個平臺都是基于 Linux 的。實際上,大部分移植只需要對某些編譯器和鏈接器開關稍加修改并重新進行編譯即可。
然而,當一個應用程序依賴于某種特定的硬件體系結構時,通常都需要進行比較大的修改。這份移植指南會重點介紹一下 Linux on x86 和 Linux on POWER 之間的區別,并提供了一些建議,讓您可以將自己的 x86 代碼移植到 Linux on POWER 平臺上。
規劃
當您將應用程序移植到一個新的平臺上時,必須要正確地進行規劃。要對移植進行充分的準備,您應該:
這些任務都假設您的公司已經決定要將自己目前在 x86 平臺上運行的應用程序移植到 Linux on POWER 平臺上。如果您的情況并非如此,可能更想多了解一些有關 Linux on POWER 的特性和功能,那么您在閱讀本文之前,就應該先參閱一下 “Linux on POWER:開發概覽” (developerWorks,2005 年 3 月)。
注冊 Chiphopper 計劃
如果您的 Linux on x86 程序是用于商業用途的,而且代碼是使用 C/C++、Java™ 或二者混合編寫的,那么它可能就會是 IBM eServer Application Advantage™ for Linux(Chiphopper)程序的一個理想候選者。Chiphopper 提供了一些免費的工具和技術支持,可以幫助您很容易地實現 Linux on x86 上現有的程序到所有 IBM eServer 和中間件平臺的移植、測試和技術支持。這可以幫助您最大限度地把握 Linux 市場機會,同時能夠將成本控制到最低。有關 Chiphopper 計劃的更多信息,以及要確定您是否具備申請資格,請參閱 參考資料 一節的內容。
如果您的應用程序并不滿足 Chiphopper 計劃的要求,或者您希望自己進行移植,那么可以繼續閱讀下一節的內容:理解 POWER 平臺的區別。
理解 POWER 平臺的區別
要移植到的 POWER 平臺決定了可以使用哪些優化選項來編譯程序。當使用 XL C/C++ 編譯器時,這尤其重要,本文稍后就會詳細討論這個問題。
在 2004 年,IBM 發布了 POWER5 處理器,這是 POWER 家族處理器中最新的一代產品,所有 POWER 家族的處理器都是基于類似的基本架構的。除了具有以前版本的 POWER 芯片的優點之外,POWER5 處理器都具有內建的虛擬化能力,包括 IBM 的 Micro-Partitioning™(微分區)、DLPAR(Dynamic Logical Partitioning,動態邏輯分區)、虛擬存儲、虛擬以太網和 CoD(Capacity on Demand)。有關 POWER5 虛擬化的更多信息,請參閱“Linux on POWER: An overview for developers”(developerWorks,2005 年 3 月)。
如果您要同時移植到基于 POWER4 和 POWER5 處理器的服務器上,可以在使用 XL C/C++ 編譯器時對 -qarch
和 -qtune
使用不同的標記來對應用程序進行優化。到底應該使用哪些具體的標記以及合適使用這些標記將在本文稍后進行介紹。
確定使用哪個 Linux for POWER 發行版
SUSE LINUX Enterprise Server(SLES)for POWER 是 SUSE、IBM 和開源社區經過 4 年多努力的結晶。除了要為 POWER 架構提供 64 位的內核之外,SLES9 現在還包括一個 64 位的運行時環境,以及用來編譯 64 位版本的流行開源軟件(例如 Apache Web 服務器或 MySQL)所使用的 GCC 工具鏈。IBM XL 編譯器是為對性能要求很高的應用程序準備的編譯器,使用它以及 SLES9 所提供的 64 位 Linux on POWER 環境(包括 IBM eServer OpenPower™、IBM eServer p5、IBM eServer i5 和 IBM eServer BladeCenter™ JS20 已經),可以提供為開發和部署 Linux 解決方案提供一個空前優秀的平臺。有關 SUSE LINUX 的更多信息,請參閱 參考資料 一節。
Red Hat Linux 在桌面和企業級的 Linux 市場方面都是被廣泛認可的業界領導者。在最新的 Red Hat Enterprise Linux Advanced Server(RHEL4)中,Red Hat 在 V3 版本的基礎上又提供了很多重要的技術改進。具體到開發領域來說,它包含了對安全性方面的改進,增強了服務器的性能和可擴展性,并增強了桌面應用的能力--所有這些都可以改進都可以確保與之前的版本保持高度的兼容性。RHEL4 是世界上領先的專注于企業級市場的 Linux 環境。有關 RHEL4 的更多信息,請參閱 參考資料 一節的內容。
決定是要使用 SLES 還是 RHEL,對移植過程并不會產生什么直接的影響。然而,要知道 SUSE 和 Red Hat 具有不同的發行版本,對于二進制兼容性也有不同的策略,這可能會影響到您長期的應用程序更新決策。
除了這兩個 IBM 所支持的 Linux 發行版本之外,還有其他幾個發行版本也可以在 Power 體系結構上運行,包括 Yellow Dog、Debian Linux 和 Gentoo(請參閱 參考資料)。
遷移至 GNU Make
如果您現在還沒有使用 GNU Make 來編譯程序,可以先考慮遷移到這上面來。使用一個工具來控制生成可執行程序,而不是依賴于一些腳本或直接與編譯器進行交互來生成可執行程序,這是一個很好的編程實踐。大部分 C 和 C++ 程序員都使用 Make 作為編譯工具。切換到 GNU Make 上,讓您可以在多個平臺上使用相同的編譯工具 makefile 確保編譯操作都是一致的。GNU Make 在 SLES9 和 RHEL4 中都已經集成了。有關 GNU Make 的更多信息,請參閱 參考資料 一節的內容。
理解 x86 和 POWER 體系結構的區別
在將 x86 平臺上的 Linux 應用程序移植到 POWER 架構上之前,您需要了解體系結構特有的幾點區別。下面是這兩種體系結構的一些區別--都是需要特別注意的一些問題:
Endianness(字節次序)
POWER 處理器使用的是 big-endian 的體系架構,而 x86 處理器使用的是 little-endian 的體系架構。本節將介紹 endianness (也稱為字節次序,byte ordering)的問題,并介紹處理這種問題的技術。開發者在將應用程序、設備驅動程序或數據文件從 x86 體系結構遷移到 POWER 體系結構上時,通常會碰到字節次序的問題。
Big endian 和 little endian
Endianness 是指數據元素及其各個字節是如何在內存中進行存儲和尋址的。在一個多位組成的數字中,數量級越大的數字就認為是越重要的。例如,在一個 4 位數字 8472 中,4 就比 7 重要。同理,在多字節的數字數據中,該字節中所代表的數字越大,它也就越重要。例如,16 進制的數字 0x89ABCDEF 可以分成 4 個字節:0x89、0xAB、0xCD 和 0xEF,它們代表的數值分別為 0x89000000、0xAB0000、0xCD00 和 0xEF。顯然,字節 0x89 的值最大;因此,它是最重要的值,而字節 0xEF 是最小的一部分,因此它最次要。
在將一個數字放到內存中時,從最低地址開始,只有兩種選擇:
下圖顯式了 big-endian 和 little-endian 處理器是如何在內存中存放一個 32 位的 16 進制數值的,例如 0x89ABCDEF:
圖 1. Big-endian 和 little-endian 處理器存放 16 機制的數值
0x89 是最重要的字節,0xEF 是最次要的字節。在 big-endian 的系統上,最重要的字節被保存在最低的內存地址中。在 little-endian 的系統中,最次要的字節被保存在最低的內存地址中。
如果一個程序將一個字寫入內存,然后有從相同的位置作為一個字將其讀出,那么字節次序就不是什么問題,因為在引用某個變量時,它看到的值是相同的。如果一個程序試圖按照一個字節來讀取相同的值(而該值是按照一個字寫入的),那么根據處理器是 big endian 還是 little endian,所讀取的值就可能有所不同。
POWER 處理器家族都使用 big-endian 數據布局,而 x86 處理器家族則都使用 little-endian 數據布局。在將 x86 程序遷移到 POWER 平臺上時,確定哪些代碼段是依賴于 endian 的,并將它們轉換為 big-endian 等效的代碼是非常重要的。
處理 endianess
本節將介紹如何判斷代碼中哪些部分是依賴于 endian 的,以及如何將這些代碼轉換成正確的 endian 格式。
依賴于 endian 的代碼
對于數據的不一致引用是 C 語言的優點,這使得它在系統級軟件的編程中非常通用,包括操作系統和設備驅動程序。這包括類型轉換、指針操作、聯合、位域、結構以及靈活的類型檢查。然而,這些特性同時也是 endianness 移植問題的源頭。我們可以考慮以下的代碼:
|
|
在 x86 系統上,結果如下:
|
在 POWER 系統上,結果如下:
|
endianness 的問題從表面上來看是由于 val
而引起的,它在被讀取時,是一個字節一個字節從最重要的字節開始讀取的。
雖然基于 POWER 處理器的系統可以支持 big-endian 的數據存儲模型,但是有一個例外:其 I/O 總線。IBM Micro Channel® 以及最新的 PCI 都是基于 little-endian 的。在 POWER 系統中,I/O 控制器是系統總線與 I/O 總線之間的橋梁,它提供了一種功能,可以在從設備讀寫數據時,將這些數據在 little endian 和 big endian 格式之間進行轉換。這種數據轉換功能對于 Direct Memory Access(DMA)和 Program I/O(PIO)或 Memory-Mapped I/O(MMIO)數據全部適用。實際上,I/O 控制器會將數據作為字節流,這樣系統中的字節 0 就可以對應 I/O 中的字節 0,字節 1 對應字節 1,依此類推。結果是,在移植與 I/O 無關的代碼時,little-endian 的代碼應該保持不變,因為 I/O 設備也是基于 little-endian 的。然而,我們建議您要確定所有依賴于 endian 的代碼(這可以檢查代碼實現,也可以使用諸如 lint 之類的編程工具實現),并手工進行這種轉換。
除了與 I/O 有關的程序之外,用來進行 TCP/IP 協議處理的程序可能也具有依賴于 endian 的代碼。因為 TCP/IP 協議指定自己的數據格式是 big endian 的,而一個基于 x86 的程序在開始進行數學計算之前,可能會將 TCP/IP 數據轉換成自己的 endianness 格式(little endian)。實際上,在 POSIX 標準(Portable Operating System Interface)中,已經定義了一些轉換程序。這些程序包括 htonl()
、ntohl()
、htons()
和 ntohs()
。這些程序名字中的 s
代表 short,l
代表一個 32 位的數據。雖然調用這些函數的程序應該不會有什么 endianness 的問題,但是可能某些依賴于 endian 的代碼會顯式地自行操作 TCP/IP 數據。
編寫 endian 中立的代碼
如果一個程序能夠移植到不同 endianness 的平臺上并能維持自己的功能,那么它就被認為是 endian 中立的。換言之,其功能與所運行平臺的 endianness 之間沒有什么關系。以下是編寫 endian 中立的代碼的一些建議:
|
|
BYTE_ORDER
選項的值:-DBYTE_ORDER=BIG_ENDIAN
。這樣在一個具有不同字節次序的新平臺上編譯時,就不用對設備驅動程序或應用程序的每個文件都進行編輯了。相反,您可以只編輯用來編譯驅動程序或應用程序的 makefile 即可。
|
POWER | x86 | |||
ILP32 | ILP64 | ILP32 | ILP64 | |
char | 8 | 8 | 8 | 8 |
short | 16 | 16 | 16 | 16 |
int | 32 | 32 | 32 | 32 |
float | 32 | 32 | 32 | 32 |
long | 32 | 64 | 32 | 64 |
long long | 64 | 64 | 64 | 64 |
double | 64 | 64 | 64 | 64 |
long double | 64/128* | 64/128* | 96 | 128 |
pointer | 32 | 64 | 32 | 64 |
-qlongdouble
選項,可以將其設置為 128 位的。
所有有關數字類型的定義在 POWER 和 x86 平臺上都可以在 /usr/include/limits.h 中找到。
現在大部分 x86 平臺上的 Linux 應用程序都是以 32 位模式運行的。然而,隨著 x86 64 位擴展的出現(x86-64),越來越多的程序將會直接編寫為 64 位的。在將 x86 應用程序移植到 POWER 平臺上時,您應該使用與源環境匹配的 Linux POWER 環境。換言之,在遷移到 POWER 平臺上的過程中,要避免從一個 32 位編程模型遷移到 64 位的編程模型,因為這種嘗試并不是單純的移植,而是一次開發任務。如果您將一個 32 位的 x86 應用程序移植到 64 位 POWER 編程模型中,那么可以將這次遷移分為兩個步驟:
這就是說,如果一個程序可以滿足以下條件,就應該被移植到 64 位環境中:
可以從遷移到 64 位程序中獲益的一些程序包括:
一個程序可以保持是 32 位的,但仍然可以在 64 位的 Linux on POWER 內核上運行,而不需要修改代碼。IBM 基于 POWER 處理器的服務器上的 Linux 可以支持在 64 位體系結構上同時運行 32 位和 64 位的應用程序,而不會造成這兩種模式的性能降低,這是因為 64 位的 POWER 體系結構中包含了對本地 32 位模式的完全支持。
在不同的平臺(從 x86 到 POWER)或編程模式(從 ILP32 到 LP64)之間移植程序時,您應該考慮不同環境中數據寬度和對齊設置的不同,這樣才能防止出現可能的性能降低或數據崩潰的問題。
在從 x86 ILP32 移植到 POWER ILP32 上或從 x86 LP64 移植到 POWER LP64 上時,注意在 表 1 中,所有的基本數據類型的寬度都是相同的,long double 例外,對于 64/128 位的 IPL32 來說,它是 96 位;而對于 64/128 位的 LP64 來說,它是 128 位。這意味著您應該盡可能地檢查以下代碼中與 long double 數據類型有關的地方。如果您計劃要使用 XL C/C++ 編譯器,請使用 -qlongdouble
編譯標記來保證 long double 數據類型具有最好的可移植性。
數據對齊
在不同的平臺或 32 位和 64 位模式之間移植程序時,要考慮不同環境中對齊設置的不同,從而避免出現可能的性能降低和數據崩潰的問題。最好的實踐方法是確保數據都是自然對齊的。自然對齊的意思是說將數據項存儲在是其大小的整數倍的地址處(例如,8 字節的數據的地址就應該是 8 的整數倍)。對于 XL C/C++ 編譯器來說,聚集類型(C/C++ 結構/聯合和 C++ 類)中的每種數據類型都會根據 linuxppc 或位填充規則按照字節邊界進行對齊,其中 linuxppc 是缺省值,它是自然對齊的。linuxppc 也是與缺省的 GCC 對齊規則兼容的。表 2 顯式了 POWER 和 x86 上的對齊值,以及它們的數據類型的寬度(以字節為單位)。
POWER | x86 | |||||||
ILP32 | ILP64 | ILP32 | ILP64 | |||||
寬度 | 對齊 | 寬度 | 對齊 | 寬度 | 對齊 | 寬度 | 對齊 | |
char | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
short | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
int | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
float | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
long | 4 | 4 | 8 | 8 | 4 | 4 | 8 | 8 |
long long | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 |
double | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 |
long double | 8/16 | 8 | 8/16 | 8 | 12 | 4 | 16 | 16 |
pointer | 4 | 4 | 8 | 8 | 4 | 4 | 8 | 8 |
GCC 和 XL C/C++ 中的關鍵字 __alignof__
讓您可以了解一個對象是如何對齊的。它的語法與 sizeof
類似。例如,如果目標及其要求一個 double 類型的值按照 8 字節邊界進行對齊,那么 __alignof__
(double) 就是 8。
正如在 表 2 中介紹的一樣,long double 類型的變量在 x86 平臺上是按照 4 個字節進行對齊的,而在 POWER 平臺上則是按照 8 個字節進行對齊的。因此,在不同的平臺上,這種結構就有不同的布局。不要將大小和偏移量都在編碼中寫死了,這一點非常重要。相反,使用 C 語言中的 sizeof
操作可以查詢基本類型和復雜類型的大小。宏 offsetof
是一個變量,它可以獲取結構程序從該結構開始地址處的偏移量。
確定使用哪種編譯器:GCC 或 IBM XL C/C++
在 Linux on POWER 上有兩種 C/C++ 編譯器:GCC 和 IBM XL C/C++。GCC 為那些在 Linux 上編譯的代碼提供了很好的可移植性,而 IBM XL 編譯器與 GCC 相比,則提供了很好的性能改進,它可以使用更高級的優化。這兩種編譯器都提供了 32 位和 64 位的編譯模式,Linux on POWER 環境允許同時運行 32 位和 64 位的代碼,而不會降低程序的性能。
使用 GCC 編譯器進行移植
對于在多種 GCC 編譯器就是原始編譯器的平臺上開發的項目來說,GCC 編譯器通常被用來為 Linux on POWER 部署應用程序。在性能不太關鍵的情況中,例如一些小工具,這都沒有什么問題。GCC 可以使用一些只有 GCC 才理解的代碼原型,例如 GCC 特有的宏。然而,這些 GCC 特有的特性中有很多也都已經集成進到 XL C/C++ 編譯器中了。
通常,使用 GCC 來遷移代碼應該比較簡單。在大部分情況中,這只需要簡單地重新編譯一下即可,也就是之需要鍵入 make
命令即可。體系結構可能會有所區別,偶然可能會出現庫程序的版本不同的問題。但是對于大部分情況來說,在哪種體系結構上運行并無關緊要。體系結構特有的標記,例如 -m486
和 -mpowerpc64
并鼓勵在 Linux on POWER 的編譯過程中采用,因為 GCC 沒有這么豐富的處理器映射來對這些體系結構上的程序進行優化。而且,不使用體系結構特有的標記,在不同的 POWER 硬件模型之間就能保證更好的可移植性。
在 SLES9 和 RHEL4 中也包含了 64 位的 GNU 編譯器,推薦您使用這些 Linux 發行版本中所提供的編譯器。
在所有的體系結構中,庫都必須使用 -fPIC
標記進行編譯;在 x86 平臺上,GCC 會缺省就應用這個標記。在 POWER 平臺上,這個標記規定所生成的代碼必須在一個共享對象中使用。更多信息請參閱 GCC 編譯器手冊(請參閱 參考資料)。
使用 IBM XL C/C++ 編譯器進行移植
IBM XL C/C++ V7.1 是 IBM VisualAge® V6.0 for Linux 的下一個發行版本。XL C/C++ 編譯器可以作為 GCC 的一種高性能的替代品,同時它還提供了很多其他的特性。
幸運的是,XL C/C++ 使用的是 GNU C 和 C++ 的頭文件,所生成的應用程序也是被鏈接到 GCC 所提供的 C 和 C++ 運行時庫上。這意味著 XL C/C++ 編譯器會產生 GNU 的 elf 對象,后者是與 GCC 編譯器所生成的對象完全兼容的。XL C/C++ 預裝了 SMP 運行時庫來支持 XL C/C++ 編譯器的自動并行處理和 OpenMP 特性。
從 GCC 遷移到 XL C/C++ for Linux on POWER 上非常簡單。XL C/C++ 可以通過提供一個選項 -qinfo=por
來幫助實現這個任務,從而幫助您對所產生的診斷消息進行過濾,只顯示那些與移植性有關的問題。另外,XL C/C++ 也可以支持 GNU 對 gcc 和 gcc-c++ 擴展的一個子集。有關 XL C/C++ 所支持的特性的完整列表,以及哪些語法可以接受,哪些語法會被忽略,請參閱“XL C/C++ for Linux on pSeries Compiler Reference”。
要在 C 代碼中使用這些支持特性,請指定 -qlanglvl=extended
或 -qlanglvl=extc89
選項。在 C++ 中,所有支持的 GNU gcc/gcc-c++ 特性缺省都是可以接受的。此外,gxlc 和 gxlc++ 可以用來幫助在使用 GNU 編譯器編譯現有應用程序時,對 makefile 所做的修改可以降至最小。
XL C/C++ 文檔
在安裝 XL C/C++ 時,會提供以下的 PDF 文檔:
這些文檔可以在下面的地方找到:
另外還有一個 HTML 版本的產品文檔被安裝到 /opt/ibmcmp/vacpp/7.0/doc/LANG/html 目錄中。在這個目錄中,打開 index.html 文件就可以查看 HTML 文件的內容。
XL C/C++ 中的優化選項
XL C/C++ 為 IBM 硬件提供了很多優化選項。對于 Linux on POWER 來說,很多使用 XL C/C++ 編譯的程序的性能都比使用 GCC 編譯的程序有顯著的提高。注意并不是所有的優化對于所有的應用程序都是有益的。通常在編譯器所實現的優化級別與編譯時間的增長以及調試能力的減弱之間是一種平衡。
優化級別
優化級別是由編譯器選項指定的。下表對編譯器在每種優化等級下的行為進行了總結:
選項 | 行為 |
-qnoopt | 快速編譯,完全調試支持 |
-O2(與 -O 相同) | 執行編譯器開發人員認為是編譯速度和運行時性能最佳組合的優化。如果沒有使用 -qnostrict_induction 或 -qnostrict 明確否定,那么這個設置中將包含 -qstrict 和 –qstrict_induction |
-O3 | 執行內存占用大、編譯時間長或兩者都有的其他優化。當運行時改善比最大程度地減少編譯資源使用重要時,建議使用這些優化 |
-O4 和 -O5 | 執行過程間優化、循環優化和自動計算機調整 |
目標機器選項是那些可以引導編譯器為某種給定的微處理器或體系結構家族生成優化代碼的選項。通過選擇適當的目標機器選項,您可以對不同范圍的目標機器進行合適的優化:這可以是一組選定的目標處理器,一個給定家族的處理器體系結構中的一組處理器,或者某個特定的處理器。以下選項可以控制影響特定目標機器優化措施:
表 4. 影響特定目標機器的優化選項選項 | 行為 |
-qarch | 選擇應該為其生成指令代碼的處理器架構系列。默認值是 -qarch=ppc64grsq 。還可以使用以下子選項: auto、 pwr3、 pwr4、 pwr5、 ppc970、 ppc64、 ppcgr、 rs64b、 rs64c |
-qtune | 偏向于對給定微處理器上的執行操作進行優化,但這并不意味著將與指令集合架構有關的任何操作作為目標。Linux 上的默認值是 -qtune=pwr3 ??捎玫淖舆x項包括: auto、 pwr3、 pwr4、 pwr5、 ppc970、 rs64b、 rs64c |
-qcache | 定義特定緩存或內存布局。如果使用了 -qcache ,則將 -qhot 或 -qsmp 與其一起使用 |
-qhot | High-Order Transformations:該優化可以通過諸如交換、合并及展開等方法特別地提高循環性能。指定 -qhot 時,默認值為選項 -qhot=vector 。嘗試將 -qhot 與 -O2 和 -O3 一起使用。它被設計用來在沒有機會進行這種轉換時,也具有很自然的效果 |
-qsmp | 生成共享內存并行處理所需的線程代碼。指定 -qsmp 時,默認值為選項 -qsmp=auto 。如果在 OpenMP 程序中編譯且不想進行自動并行化,則使用 -qsmp=omp:noauto 。使用 -qsmp 時,總是使用 _r 編譯器調用 |
要獲得最好的目標機器選項,您應該:
–qarch
選項指定您期望代碼能夠運行良好的最小系列的機器。 –qtune
選項指定在哪種機器上的性能最好。例如,如果您的應用程序只支持 POWER5 系統,就可以使用 -O3 -qarch=pwr5 -qtune=pwr5
選項。修改緩存布局在某些情況中可能會非常有用,例如系統具有可配置的 L2 和 L3 緩存.或者整型模式會減小緩存共享級別的有效大?。ɡ?,POWER5 中雙核芯片的 SMP)。如果您的程序只要在 POWER4 上運行,或者要在 POWER4 和 POWER5 上運行,可以使用 -qarch=pwr4 -qtune=pwr4
。
POWER 平臺可以支持其他平臺上所沒有的一些指令。XL C/C++ 提供了一組內嵌的函數,它們可以直接映射為特定的 POWER 指令。使用這些函數可以消除函數調用返回、參數傳遞、堆棧調整以及其他與函數調用有關的開銷。有關所支持的內嵌函數的完整列表,請參閱“XL C/C++ C++ for Linux on pSeries Compiler Reference”安裝文檔。
然而,那些最初是想使用 GCC 編譯器進行編譯的程序在使用 IBM XL C/C++ 編譯器進行編譯時需要多加注意。您需要編輯 makefile 來體現 XL C/C++ 編譯器的正確路徑,它缺省位于 /opt/ibmcmp/ 中。您還需要為特定的體系結構設置正確的優化標記(例如對于 IBM POWER5 來說是 -03 –qarch=pwr5 –qtune=pwr5
)。
除了對各種 POWER 體系結構進行優化的優化選項之外,XL C/C++ 編譯器還可以使用通用的模式來編譯軟件。這可以保證在所有的 POWER 體系結構上程序都是兼容的,代價是性能不如對具體某種體系結構進行優化后的結果好。在編譯 64 位的代碼時,編譯器必須要為 64 位的編譯給出一個標記(即 -q64
),因為它缺省是 32 位模式。
下面是使用 XL C/C++ 編譯器來編譯面向 GCC 的代碼時的一些技巧:
-q
參數允許使用這種注釋:-q cpluscmt
。當使用這個標記編譯 C 代碼時,C 和 C++ 風格的注釋都會進行解釋。 $CC 和 $CFLAGS
,這樣就可以讓配置腳本生成 makefile,而不需要手工進行編輯。 -target=
標記來為 GCC 或 XL C/C++ 設置這個編譯選項。 $COMPILER_PATH/bin/cc
就可以得到完整的參數列表。
GCC 和 XL C/C++ 編譯器選項的比較
下 表 對 GCC 和 XL C/C++ 常用的編譯器選項進行了比較:
GCC | XL C/C++ C/C++ | 說明 |
-v | -v, -V, -# | 開啟詳細模式 |
-p/-profile | -p | 設置編譯器生成的對象文件進行概要分析 |
n/a | -q32, -q64 或設置 OBJECT_MODE 環境變量 | 創建 32 位或 64 位對象。GCC 64 位編譯器位于 /opt/cross/bin 中 |
-fsyntax-only | -qsyntaxonly | 執行語法檢查,不生成對象文件 |
-fpic | -qpic=small | 生成共享庫中使用的 Position-Independent Code。在 XL C/C++ 中,Global Offset Table 的大小不超過 64 Kb。如果指定 –qpic ,而無任何子選項,則假設 -qpic=small 。如果指定了 -qmkshrobj 編譯器選項,則啟用 –qpic 選項 |
-fPIC | -qpic=large | 允許 Global Offset Table 大于 64 Kb |
-pthread | -qthreaded or _r invocation mode | 創建在多線程環境中運行的程序 |
-fno-rtti | -qnortti | 對于異常處理和 typeid 和 dynamic_cast 操作符的使用,禁止生成運行時類型 –qrtti 識別(RTTI)。在 XL C/C++ 中,默認值為 -qnortti |
-static | -qstaticlink | 使用這個選項生成的對象將無法與共享庫進行鏈接 |
-static-libgcc | -qstaticlink=libgcc | 指示編譯器與 libgcc 的靜態版本鏈接 |
-shared | -qmkshrobj | 指示編譯器生成共享對象 |
-shared-libgcc | -qnostaticlink=libgcc | 指示編譯器與 libgcc 的共享版本鏈接 |
-Wl,-rpath | -Wl,-rpath 或 –R | 傳遞用冒號分隔的目錄列表,用它來指定運行時鏈接程序搜索的目錄 |
-fno-implicit-templates, -frepo | -qtempinc, -qtemplateregistry, -qtemplaterecompile | 模板實例化 |
-w | -w | 取消警告消息 |
-warn64 | 允許對長型到整型的截斷舍位(long-to-integer truncation)進行檢查 | |
-qinfo=<…> | 生成信息消息 | |
-fpack-struct | -qalign=bit_packed | 使用 bit_packed 排列規則 |
-qalign=linuxppc | 使用默認 GCC 排列規則來維護與 GCC 對象的兼容性。這個值是默認值 | |
-O,-O2,-O3 | -O,-O2,-O3,-O4,-O5 | 優化級別 |
-qarch, -qtune, -qcache | 特定處理器的優化選項 |
請參閱“How to use IBM XL C/C++ Advanced Edition V7.0 for Linux on POWER: A guide for GCC users”(developerWorks,2004 年 10 月)中有關 IBM C/C++ 編譯器的更多信息。
移植
在完成規劃的所有步驟之后,您就應該準備好開始進行移植了。本節將簡要討論成功將程序移植到 Linux on POWER 上的一些推薦步驟。
make
。如果您在編譯過程中碰到了錯誤,那么通常都是編譯器的或鏈接器的錯誤,或者是程序的語法錯誤。通常通過 makefile 修改編譯器選項或修改代碼中的語法都可以修復這些錯誤。編譯器的參考手冊和編程指南是這個過程中最好的參考資料。對于 IBM XL C/C++ 來說,請參考“XL C/C++ for Linux Compiler Reference”(compiler.pdf)和“XL C/C++ for Linux Programming Guide”(proguide.pdf)。對于 GCC 來說,編譯器的參考手冊和編程指南都可以在 gcc.gnu.org/onlinedocs 中找到。圖 2. 上面介紹的移植操作 6 個步驟中第一個步驟的流程
結束語
Linux on POWER 提供了一個企業級的 Linux 環境,以及完整的 32 位和 64 位的應用環境和工具鏈。Linux on POWER 提供了兩套編譯器集,它們可以簡化開源代碼的移植,并促進廣受好評的 POWER 體系結構這種高性能的平臺的采用。將您的 x86 平臺上的程序移植到 Linux on POWER 上,您就可以在 POWER 架構上充分利用程序的性能,現在以及在 Linux 操作系統上提供的一些前所未有的工具??傊?,Linux on POWER 是部署高性能的 Linux 程序的業界領先的平臺。
原文轉自:http://www.anti-gravitydesign.com