級別: 初級 |
Linux 技術顧問, IBM
2005 年 3 月 24 日
2005 年 7 月 更新
了解二進制兼容性,因為它關系到運行在 POWER™ 上 Linux® 中的不同操作環境。研究 IBM® 支持的兩個 Linux on POWER 發行版本,Red Hat Enterprise Linux(RHEL)和 SUSE LINUX Enterprise Server(SLES),注意各版本之間的二進制兼容性。通常,可以從基于 2.4 內核的 RHEL3 向基于 2.6 內核的 RHEL4 進行順利遷移,因為這兩個版本之間維護了穩定的應用程序二進制接口(Application Binary Interface,ABI),并將 RHEL4 的很多特性反向移植到了 REHL3 中。盡管基于 2.4 內核的 SLES8 與基于 2.6 內核的 SLES9 的線程模型有所不同,但在很多情形下,這兩個版本之間仍保持了二進制兼容性。了解可以提高 Linux on POWER 應用程序性能的新技術,將來可以遵循這些步驟來確保多個版本之間的二進制兼容性。
簡介
當前有很多不同的 Linux 發行版本可用。雖然 Red Hat 和 SUSE LINUX 是受 IBM 支持的 Linux on POWER 解決方案提供商,不過,其他發行版本,比如 Gentoo 和 Debian,也同樣正在被 Linux on POWER 所接受。應用程序開發人員通常希望確保他們的應用程序能在多種發行版本上運行,在給定發行版本的不同版本上運行。通過了解二進制兼容性所涉及的問題,可以達成這些目標。本文定義了二進制兼容性,討論了嘗試保持兼容性時出現的考慮事項,并介紹了不同版本之間的遷移,即 Red Hat Enterprise Linux 版本 3 和版本 4,以及 SUSE LINUX Enterprise Server 版本 8 和版本 9。文中還包含了一些慣例,在多種發行版本中運行某個應用程序時,可以遵循這些慣例來確保兼容性。
表 1 提供了一些軟件級別的消息,以及從 RHEL3、RHEL4、SLES8 和 SLES9 中獲得的受支持特性,本文中對這些進行了詳細介紹:
表 1. RHEL 和 SLES 發行版本中受支持的特性和代碼級別
SLES8 SP4 | RHEL3 U4 | SLES9 | RHEL4 | |
內核 | 2.4.21 | 2.4.21 | 2.6.5 | 2.6.9 |
glibc | 2.2.5 | 2.3.2 | 2.3.3 | 2.3.4 |
SMT | ![]() |
![]() |
![]() |
![]() |
NPTL | ![]() |
![]() |
![]() |
![]() |
NUMA | ![]() |
![]() |
![]() |
![]() |
JDK | IBM 1.3.1 | IBM 1.4.2¹ | IBM 1.4.2 | IBM 1.4.2 |
Apache | 1.3.26 | 2.0.46 | 2.0.49 | 2.0.52 |
您可以使用圖 1 所示的流程圖來確定某個應用程序在 RHEL or SLES 中是否具備二進制兼容性。
圖 1. 確定應用程序的二進制兼容性
二進制兼容性概述
應用程序二進制接口(ABI)的應用促成了 Linux on POWER 二進制兼容性。編譯過的二進制代碼可以通過 ABI 接口訪問某個操作系統及其服務。當多個操作系統支持相同的 ABI 時,就使得相同的二進制代碼可以在各種環境中運行。在“64-bit PowerPC ELF Application Binary Interface Supplement 1.7”文檔(IBM)中可以找到針對 PowerPC® Executable and Linking Format(ELF)ABI 的補充支持的更多信息(請參閱 參考資料。)
二進制兼容性是獲得二進制代碼并在給定處理器家族的多種環境中運行它的能力。這些環境可以是同一 Linux 發行版本的不同版本,也可以是完全不同的發行版本。一個示例是,在使用 SLES9 的基于 POWER4™ 處理器的系統中編譯并運行的二進制代碼,并在同樣使用 SLES9 的基于 POWER5™ 處理器的系統中去執行它。另一個示例是,取得在使用 RHEL3 的基于 POWER4™ 處理器的系統中編譯并運行的二進制代碼,然后在使用 SLES9 的基于 POWER5™ 處理器的系統中去執行相同的二進制代碼。
處理器兼容性
處理器兼容性是與 Linux on POWER 的二進制兼容性關系密切的一個話題。這一節將介紹不同的 64-位 POWER 處理器之間的兼容性,以及 32-位 PowerPC 處理器與 64-位 POWER 處理器之間的兼容性。
POWER 處理器兼容性
“二進制兼容性概述”中的最后一個示例涉及到了在不同的處理器類型中運行二進制代碼 —— POWER4 處理器和 POWER5 處理器。POWER5 處理器包含了對 POWER4 架構的改進,同時保持了兩者間的二進制兼容性,這就使得您可以在這兩個平臺上運行相同的應用程序。同樣的二進制代碼也可以運行在 IBM® eServer™ BladeCenter™ JS20 上,它使用的是基于 PowerPC® 970 的處理器。這種處理器是 POWER4 處理器的單核心(single-core)版本,它保持了與 Power 架構家族其他成員的二進制兼容性。
PowerPC 與 POWER 處理器兼容性
在本地 32-位 PowerPC 環境以及 64-位 POWER 環境中運行的 32-位應用程序之間存在二進制兼容性。也有可能在 64-位 Linux on POWER 系統中所生成的本地 Linux PowerPC 環境中執行 32-位二進制代碼。這一兼容性可能要歸于以下原因:
有一些生成 32-位和 64-位 Linux 二進制代碼的不同方法(取決于開發平臺):
表 2 展示了如何為各種開發平臺生成 32-位和 64-位 Linux 二進制代碼:
表 2. 生成 32-位和 64-位 Linux 二進制代碼
開發平臺 | 編譯器 | 生成的 Linux 二進制代碼 |
32-bit Linux on PowerPC | Native GCC C 編譯器 | 32-bit |
64-bit Linux on POWER | Native XL C/C++ or GCC C compiler | 32-bit 或者 64-bit |
32-bit Linux on PowerPC 或者 64-bit Linux on POWER |
crosstool 等交叉編譯器 | 32-bit 或者 64-bit |
雖然已經展示了 32-位和 64-位環境之間的兼容性,但這并不意味著發行版本官方支持此類兼容性。Red Hat 支持 RHEL3 和 RHEL4 之間的 32-位和 64-位向前和向后兼容性,而當從 SLES8 向 SLES9 遷移時,SLES8 只支持 32-位向前兼容性。
表 3 展示了 RHEL 和 SLES 的不同版本上 32-位和 64-位應用程序的向后和向前兼容性:
表 3. RHEL 和 SLES 發行版本中的 32-位和 64-位兼容性
發行版本 | 32-bit | 64-bit |
RHEL3 RHEL4 | ![]() |
![]() |
RHEL4 RHEL3 | ![]() |
![]() |
SLES9 SLES8 | ![]() |
![]() |
SLES8 SLES9 | ![]() |
![]() |
優化性能
2.6 內核和 POWER5 架構都具有可以提高應用程序性能的特性。這些提高來自于不同的程序庫、處理器特性以及得到更新的編譯器。有些情況下可以直接提高性能,不需要對應用程序進行任何修改,不過,在其他情況下,性能提高需要重新編譯源代碼。重要的是要緊記:通過重新編譯來獲得性能提升可能會影響某些環境中的二進制兼容性。這一節將給出 2.6 內核以及 POWER5 架構的新特性的一些示例,這些新特性有益于提高應用程序的性能。
NUMA
非一致內存訪問(Non-uniform Memory Access,NUMA)是用于 Linux on POWER 的 2.6 內核所支持的新特性。NUMA 解決的是系統中特定的處理器(取決于它們在總線上的位置)訪問內存中特定區域所需時間比其他處理器更長的問題。通過使用更多的內存總線,并令每條總線上處理器更少,NUMA 減少了系統共享內存總線的沖突。當系統的處理器較少時,這不是什么問題,但當系統中有很多處理器時,這樣可以提高性能。由于 POWER5 架構擴展到 64 個處理器,Linux on POWER 可以受益于 2.6 內核的這一新特性。大部分應用程序將受益于 2.6 內核級 NUMA 支持。希望能進一步提高性能的應用程序可以使用用戶空間 NUMA API。 RHEL4 附帶了用戶空間 NUMA API,在 NUMA Group 主頁上可以找到關于如何使用這些 API 的更多資料。(請參閱 參考資料。)
編譯器改進
您可能會考慮通過重新編譯,借助用于 Linux on POWER 的最新編譯器的新特性來獲得性能提高。高性能編譯器 IBM XL C/C++ Version 7.0 可以用于 RHEL3、RHEL4 和 SLES9,可以進一步提高基于 POWER5 的系統的性能。使用 -qarch
和 -qtune
選項來為其相應的架構進行優化。例如,要為 POWER5 進行優化,要使用下面的選項: -qarch=pwr5
和 -qtune=pwr5
。
XL C/C++ 編譯器也包含了對 PowerPC 970 處理器上向量多媒體擴展(Vector Multimedia Extensions,VMX)的支持,使用的是 -qaltivec
選項。
GNU Compiler Collection 包括很多語言的編譯器。相對于版本 3.2,版本 3.3 已經得到了改進,包括對它的 C 編譯器(gcc)的特定于 POWER5 處理器的優化。-mcpu=power5
和 -mtune=power5
標記已經得到了支持,結果是能夠支持以 POWER5 架構為目標的寄存器使用和指令調度參數。另外也有用于 IBM PowerPC 970 處理器的 VMX 向量擴展,可以提高向量化代碼的性能。雖然這些優化在它們各自的架構上提高了性能,但是可能會影響運行在其他平臺上的應用程序的二進制兼容性。
在 developerWorks 文章“How to use IBM XL C/C++ Advanced Edition V7.0 for Linux on POWER: A guide for GCC users”中可以找到關于如何使用針對 Linux on POWER 的 XL C/C++ 編譯器的更多資料。
SMT
在遷移到基于 2.6 的 Linux 內核時,同步多線程(Simultaneous Multi-threading,SMT)帶來了提高性能的另一種可能。 SMT 得到了 POWER5 架構的支持,極大地提高了重量級多線程應用程序的性能。POWER5 芯片有兩個硬件指令線程,在每個周期都能夠執行多個指令,這可以提高性能。不過,對于某些非重量級線程的應用程序,SMT 可能會導致性能的下降。在引導時向 Linux 內核傳遞 smt-enabled=off
可以禁用 SMT。
其他 2.6 內核改進
RHEL4 和 SLES9 中所使用的 2.6 內核具有這些其他方面的性能改進:
從 RHEL3 遷移到 RHEL4
從 RHEL3 到 RHEL4,Red Hat 維持了一個穩定的 ABI,使得應用程序在這兩個版本之間可以順利遷移。不過,為了確保二進制兼容性, Red Hat 建議您將應用程序接口鏈接到他們定義的核心程序庫。這個列表中包括的程序庫有:
在“Red Hat Enterprise Linux 4 Application Compatibility”一文中描述了核心程序庫以及其他兼容性問題(請參閱 參考資料)。如果某個應用程序使用了此核心程序庫集之外的程序庫,可能仍然會保持兼容性,但應該進行進一步的回歸測試。應用程序可能無法保持二進制兼容性的其他情況包括:應用程序靜態鏈接到任何程序庫、依賴內核級接口,或者與 POSIX 標準或者 64-位 POWER ABI 定義相沖突。
不僅 ABI 在 RHEL3 和 RHEL4 之間是穩定的,而且 RHEL4 中可以找到的 2.6 內核的很多特性也已經反向移植到了 RHEL3。這使得 RHEL3 應用程序可以利用同步多線程(SMT)和 Native Posix Thread Library(NPTL)等特性來獲得 RHEL4 中所包含的性能提高,而無需重新編譯它們的源代碼。這些應用程序也會獲得如本文前面所描述的伴隨 2.6 內核而來的性能提高。
不過,在兩種情形下,在 RHEL4 中重新編譯可以提高應用程序的性能:
當為了性能的提高而重新編譯您的應用程序時,必須要考慮影響二進制兼容性的風險。
不過,在大部分情況下,當從 RHEL3 遷移到 RHEL4 時,不必付出額外的工作。
從 SLES8 遷移到 SLES9
由于兩個版本間的一些重要變化,從 SLES8 到 SLES9 的遷移需要考慮稍微更多一些事項。具體地說,SLES8 基于 2.4.21 內核,使用的是 2.2.5 版本的 glibc,而 SLES9 基于 2.6 內核,使用的是 2.3 版本的 glibc。另外,SLES9 已經轉移到了 NPTL 線程模型,而 SLES8 仍然在使用較老的 LinuxThreads 模型。在下面的“線程模型”中對線程模型的變化所帶來的問題進行了描述。雖然使用通用程序庫的非線程化應用程序在 SLES 版本間保持二進制兼容性的幾率更大,但是也應該進行回歸測試以保證質量。
如 RHEL,在某些情形下,重新編譯源代碼可能會為將要在 SLES9 上運行的應用程序帶來好處。例如,通過利用 SLES9 中得到增強的編譯器,應用程序可能會獲得性能的提高。SMT 也是 SLES9 中的一個新特性,可以提高重量級線程應用程序的性能。
通常,大部分非線程的應用程序在 SLES8 和 SLES9 中是二進制兼容的。不過,由于程序庫和內核版本的重要變化,對嘗試優化自己應用程序性能的開發人員來說,重新編譯源代碼可能是最好的選擇。
確保發行版本間的兼容性
編譯能夠跨多種 Linux 發行版本移植的應用程序可能看起來是一項艱難的任務,不過,遵循一些簡單的慣例就可以完成它。大部分發行版本的最新版本通常包含相同版本號的程序庫的內核版本。大部分發行版本還會使用類似的配置和數據文件的格式。當嘗試編寫跨不同發行版本移植的應用程序時,可以遵循下面的部分所給出的一些指導方針。
很多 Linux 發行版本都包含相同的 ABI 和通用的核心程序庫集。不過,每個發行版本對核心的定義會稍有不同,這就意味著當宣稱您的應用程序支持某個給定的發行版本上時,總是需要進行回歸測試。例如,如果您仔細研究 RHEL 和 SLES 發行版本所包含的 glibc 程序庫,您會發現 RHEL3 所包含的是版本 2.3.2,SLES9 是 2.3.3,而 RHEL4 所附帶的是 2.3.4,都非常類似。輔助版本號的區別通常是缺陷的修復,而沒有新加的特性。RHEL3、RHEL4 和 SLES9 也使用了類似的線程模型,所以,任何鏈接到通用程序庫的應用程序都應該能夠在所有這三個操作環境中運行。您也會在 Gentoo 和 Debian 等其他發行版本中找到通用程序庫。
文件層級標準(File Hierarchy Standard,FHS)定義了在通常的類-UNIX® 系統中文件和目錄的布局方式。如果您的應用程序要依賴于其他配置和數據文件,那么應該使用 FHS。FHS 的主要用途是為應用程序提供一個能找到標準配置文件的通用位置。在文件系統層級標準(Filesystem Hierarchy Standard)主頁上可以找到關于 FHS 的更多資料。(請參閱 參考資料。)
雖然通常不可能聲稱能夠確??缢?Linux 發行版本的二進制兼容性,但是,通過遵循下面這些慣例,您可以聲明支持大部分當前發行版本。
二進制兼容性方面的考慮事項
盡管已經從 ABI 和處理器家族的角度定義了二進制兼容性,但是當確定某個應用程序是否能夠跨多種環境運行時,還有其他兼容性需要考慮。有一些示例,比如線程模型、底層內核依賴、中間件以及核心程序庫。這一節將介紹這些需要考慮的事項以及 Linux on POWER 如何處理它們。
線程模型
隨著 glibc 2.3 的發布和 Linux 內核從版本 2.4 到版本 2.6 的變遷,線程模型已經發生了變化。glibc 2.2 版本和 2.4 內核中所使用的傳統 LinuxThreads 模型已經被 Native Posix Thread Library(NPTL)所取代。NPTL 已經徹底重寫,這為重量級線程應用程序帶來了顯著的性能提高。在 Red Hat 文章“The Native POSIX Thread Library for Linux”中可以找到關于 NPTL 規范的更多細節。(請參閱 參考資料。)
SLES8 基于 2.4 內核,使用的是 Linux Thread 模型,當嘗試在使用 NPTL 線程模型的 SLES9 上運行線程化的應用程序時,這會引發問題。這個問題有兩個解決方案:
LD_ASSUME_KERNEL
環境變量,它在 SLES9 中提供了與 LinuxThreads 模型的向后兼容性。通過設置 這個變量,鏈接器會認為運行的是使用較老的 LinuxThreads 模型的 2.4 內核。Red Hat 開發者 Ulrich Drepper 詳細地解釋了 LD_ASSUME_KERNEL
(請參閱 參考資料)。
Red Hat RHEL3 使用的也是 2.4 內核,不過它從 2.6 內核反向移植了 NPTL 線程支持。這就使得線程化的應用程序可以在 RHEL 的不同版本之間順利進行遷移。
底層內核依賴
當在不同的操作環境中運行應用程序時,底層內核依賴是要考慮的另一個方面。作為一個示例,如果應用程序編寫時使用的是某個文件系統中的固定編碼的值,那么當信息從 /proc 文件系統移到 sysfs 文件系統時可能會不兼容。先前的 /proc 文件系統是一個處于內存中的文件系統,讓用戶空間能夠訪問內核數據結構,這些數據結構中包含有系統和設備狀態信息。這些信息從 /proc 文件系統遷移到 sysfs 文件系統中。/proc 文件系統仍然存在,不過只是包含進程信息。
系統信息從 /proc 文件系統移到 sysfs 文件系統的一個示例是通用串行總線(Universal Serial Bus,USB)設備列表的存儲。在基于 2.4 內核的系統上編寫的應用程序會發現,這個設備列在 /proc/bus/usb/devices 中。隨著向 2.6 內核和 sysfs 文件系統的遷移,此信息已經移到了 /sys/bus/usb/devices。此信息的移動可能會導致應用程序不能正常工作。雖然這并不常見,但您需要意識到內核級中這種潛在問題。
中間件和應用程序兼容性
當前很多應用程序都不是自包含的,而是依賴于其他應用程序中間件。中間件是位于兩個應用程序之間或者應用程序與操作系統之間的一部分軟件。中間件的示例包含 IBM DB2® Universal Database for Linux、Java™ Development Kit(JDK)以及 IBM WebSphere® 應用程序。開發人員可以確定他們的應用程序支持哪個版本的中間件,但是中間件的提供者決定了他們的產品能夠運行于哪個 Linux 發行版本。在用于 Linux 的 IBM 軟件 Web 站點有用于 Linux 的 IBM 中間件列表(請參閱 參考資料)。 連同中間件一起,應用程序可能會依賴于發行版本所附帶的其他應用程序。例如 Apache web 服務器、數據庫系統(比如 mysql 和 postgresql)以及解釋語言(perl 和 python)。
作為示例,讓我們來仔細研究 Java,看它是如何影響應用程序開發人員的。Java 是一個廣受關注的通用的中間件軟件包,這要歸因于因為其平臺獨立性而存在的大量 Java 應用程序。JDK 不僅有不同的版本和提供者,用于 Linux on POWER 的還有 32-位和 64-位的版本。RHEL3 不附帶 JDK,但是它支持 IBM Developer Kit for Linux、Java 2 Technology Edition,Version 1.4.2,而 RHEL4 既附帶 IBM 32-bit SDK for Linux V1.4.2 也附帶 IBM 64-bit SDK for Linux V1.4.2。SLES8 Update4 附帶 IBM 32-bit SDK for Linux V1.3.1,而 SLES9 附帶 IBM SDK V1.4.2 的 32-位和 64-位版本。當自己的應用程序依賴于只有在版本 1.4.2 中才可用的特性時,應用程序開發人員必須意識到這些區別,因為這些特性在 SLES8 中是不可用的。
作為另一個示例,Apache web 服務器是一個不被認為是中間件的應用程序,但是很多應用程序都依賴它。Apache 的最新版本是版本 2.0, RHEL3、RHEL4 和 SLES9 都附帶它,而 SLES8 附帶的是版本 1.3。如果某個應用程序使用了只有在 Apache 2.0 中才可用的新特性,那么開發人員應該意識到他們的應用程序可能無法與 SLES8 附帶的版本 1.3 的 Apache 相兼容。
核心程序庫
當嘗試獲得二進制兼容性時,核心程序庫的重要變化也會引發問題。程序庫的重要變化之間保持了向后兼容性。這就使得使用給定程序庫的較老版本編譯的應用程序可以使用同一程序庫的新版本運行。如果修訂版本間有重要的變化,那么使用給定程序庫的最新版本編譯的應用程序將不能使用同一程序庫的較老版本運行。例如,在 SLES8 系統中使用 glibc 版本 2.2.5 編譯的二進制代碼,將可以在 SLES9 系統中使用 glibc 版本 2.3 運行,因為 2.3 版本是向后兼容的。不過,在 SLES9 上編譯的同樣的源文件將因較老的 glibc 而不能在 SLES8 系統中運行。只有當您在當前發行版本上開發應用程序,并且希望在發行版本的較老版本上(不提供較老的兼容程序庫)支持那個應用程序時,這才會引發問題。
原文轉自:http://www.anti-gravitydesign.com