白劍飛,文正國
(中國水利水電科學研究院中水科技公司,北京 100038)
H9000計算機監控系統是中國水利水電科學研究院自動化所面向水利水電工程監控與自動化應用而研制開發的分布式計算機控制系統,自1996年首次現場投運以來,不斷擴充完善,由最初的1.0版升級到4.0版,并通過了170多個水利水電工程的運行考驗,是一套成熟的水電站計算機監控系統。它結合了當代國內外最新計算機硬件產品、軟件產品、網絡技術、實時工業控制產品與未來發展趨勢,集中體現了中國水利水電科學院自動化所 (北京中水科水電科技開發有限公司)在水利水電自動化領域20多年的研制開發經驗,系統具有良好的可靠性、可變性、可擴充性和可移植性,并支持異型機互聯。
水利水電工程計算機監控系統采用的主流計算機操作系統分為UNIX操作系統 (如SUN的Solaris、HP的HP-UX、IBM的AIX)、WINDOWS操作系統以及LINUX操作系統等。因UNIX系統具有高性能、高可靠性、高安全性、網絡和數據庫功能強尤其是防病毒等特點,是大中型水電廠計算機監控系統主機的首選,但對運行維護人員的技術水平有一定要求,通常安裝UNIX系統的硬件平臺價格較高,性價比不高。而中小型水電廠多采用PC和WINDOWS技術架構的計算機作為監控系統主機,價格低廉,易于使用維護,但存在易感染病毒、性能不高等缺點。LINUX操作系統是一種類UNIX的操作系統,目前已在計算機監控系統領域開始使用,但還沒有成為主流。
H9000計算機監控系統針對不同的硬件平臺和操作系統平臺,開發了基于UNIX操作系統和基于Windows操作系統的版本,這兩個版本用戶外部界面完全相同,具有相同的性能與功能,而且軟件代碼也基本兼容。
隨著技術的進步,為了降低使用UNIX平臺的硬件使用成本,擴大UNIX的市場占有率,有些UNIX操作系統已實現從專用硬件平臺到普通PC架構硬件平臺的移植工作,比如SUN公司將Solaris操作系統從只支持SPARC平臺擴展到支持X86、X64等PC架構平臺,從而擴大了Solaris的使用范圍。如果能實現H9000計算機監控系統從基于SUN SPARC硬件平臺UNIX操作系統到基于X86 PC架構硬件平臺UNIX操作系統的移植,將對降低水電行業在計算機監控系統方面的投資、提高基于PC硬件平臺監控系統的穩定性和可靠性以及提高監控系統的市場競爭力,具有重要意義。
本文在分析基于SUN硬件平臺的UNIX操作系統和基于PC架構的UNIX操作系統差異的基礎上,研究了將H9000監控系統移植到基于PC架構的UNIX操作系統的技術。
X86架構是從Intel 8008處理器中發展而來的,X86是一個Intel通用計算機系列的標準編號縮寫,也標識一套通用的計算機指令集合。Intel公司所生產的所有CPU以及AMD、Cyrix等廠家生產的能使用X86指令集的CPU,都屬于X86系列及兼容CPU陣容。X86采用馮·諾依曼體系,使用復雜指令集,面向的是通用程序設計。
SPARC是SUN和TI公司合作開發的RISC微處理器。SPARC微處理器最突出的特點是它的可擴展性。SPARC采用哈佛結構,使用精簡指令集,強調運算速度,適用領域廣,可以用于PC也可以用于嵌入式。
基于SUN硬件平臺的UNIX操作系統是Solaris操作系統,Solaris操作系統是SUN公司研發的多用戶多任務的UNIX操作系統,分為SPARC和X86兩種版本。Solaris for SPARC版本只能安裝在基于SPARC架構處理器的服務器上,Solaris for X86版本適用于X86架構的計算機,目前有820多種X86平臺支持Solaris操作系統。
不同的硬件平臺及不同操作系統在核心機制、實現方式、用戶接口等方面的差異導致了特定平臺應用系統的內部機制存在較大差異。從系統平臺、應用軟件的角度分析,研究工作將主要涉及應用軟件設計與運行的支撐環境,應用軟件的實現機制以及跨平臺的移植方法等幾個方面。
硬件體系結構之間的差異體現在字長、字節排列順序、指令集等方面。SPARC平臺與X86平臺之間的硬件設計差異如下:
(1)字節存放順序不同:X86平臺采用的是小端字節存放順序,SPARC平臺采用的是大端字節存放順序。
(2)輸入輸出體系不同:X86平臺輸入/輸出采用特殊的指令格式,SPARC平臺輸入/輸出采用與讀寫內存相同的指令格式。
(3)數據對齊性不同:結構體中的域成員對齊方式跨平臺不同。如SPARC處理器強制double浮點變量8字節對齊方式,而X86處理器強制double浮點變量4字節對齊方式。由于不同平臺上不同的對齊方式和數據類型大小不同,造成結構體大小不同,所以應考慮在程序中使用sizeof操作碼得到具體的讀或寫數據的字節個數。
(4)字節長度不同:Solaris for SPARC系統支持32位和64位技術,而Solaris for X86系統僅支持X86處理器的32位家族。
(5)浮點操作不同:Solaris for X86系統浮點數80位寬,Solaris for SPARC系統浮點數是64位寬。由于這種不兼容性,導致計算結果可能不同。
作為應用程序的支撐平臺,操作系統通常提供系統調用和函數鏈接庫作為程序的調用接口。不同平臺內核中的進/線程調度、資源管理、圖形支撐等運行時接口內部機制存在差異。Solaris OSSPARC和Solaris OSX86的差異主要如下:
(1)對專業圖形接口程序(OpenGL)支持方面的不同;
(2)特殊指令集不同。
編譯器是與操作系統同等重要的系統軟件,它將程序代碼翻譯成可執行代碼,是操作系統生成可執行代碼的最后一步。Solaris for SPARC系統和Solaris for X86系統編譯器之間的不同如下:
(1)編譯器標志不同;
(2)線程本地存儲(TLS)存在差異。
從前邊的分析可以看出,平臺差異主要表現在硬件體系結構、操作系統和編譯器三個方面。這些差異導致的問題及解決方法分述如下。
Solaris for SPARC系統和Solaris for X86系統之間由硬件體系結構造成的不同主要有字節存放順序不同、存儲數據不同、數據對齊性不同、字節長度不同、浮點操作不同等。這些不同可能導致的問題及解決方法如下:
2.1.1 字節存放順序不同
(1)通過網絡傳輸數據時,如果運行在Solaris系統的應用程序使用標準網絡協議與其他系統通過網絡交換數據時,可以在大端字節順序系統和小端字節順序系統之間實現通訊。如果應用程序未使用任何協議而直接通過網絡傳送數據,可能會出現因字節順序不同而導致數據傳輸出現問題。這種情況下,可以使用標準C庫提供的函數實現網絡字節順序和本機字節順序之間的轉換。
(2)用指針訪問數值數據的個別字節時,可能由于底層平臺字節順序的不同得到不同的結果。這種情況下,在代碼從Solaris SPARC操作系統移到x86操作系統需要注意。為使代碼適用于多平臺,使用字節類型變量來存儲值而不使用數值數據類型;或者使用具有獨立域的結構變量來存儲每個值,使用結構體域名來獲得和設置這些值。
(3)應用程序數據存儲時,一般文件系統對字節順序是中立的。在Solaris SPARC和x86之間交換文件不是問題。應用程序存儲各平臺之間共享的原始數據可能會因字節順序出現問題。如:Solaris SPARC平臺上運行的數據將以二進制數據存儲到文件的程序,這些文件中存儲的數據是字節順序依賴的。以二進制數據存儲的文件在SPARC和x86平臺之間是不可遷移的。可以用以下兩種方法之一解決平臺之間共享數據的字節順序問題:①用文本和字符串將數據存儲成字節順序中立的格式;②在需要時進行字節順序轉換。
(4)共享內存實現方面:在字節順序相反的設備或處理器之間共享內存進行數據輸入和輸出時,為了避免附加系統調用的開銷,當通過操作系統傳送數據到高速設備時,可以在外處理器上直接將存儲區映射到應用程序地址區。共享內存映射到應用地址空間的最常見例子是圖形采集器用幀緩存器在本機和圖形處理器之間共享內存。如果處理器的字節順序不同,以圖像采集器的共享內存問題來說,對從相反字節順序設備傳送來的多字節數據,在存儲之前或加載之后進行字節交換。
2.1.2 存儲順序不同
設定了特殊存儲順序的代碼是不可移植的。要使代碼可移植,需單獨比較結構體中變量,使其不依賴于存儲順序。
2.1.3 數據對齊性不同
(1)讀/寫結構體時:大部分程序使用標準C函數讀和寫數據到永久存儲體中,這些函數需要所讀或所寫數據的字節長度值。由于不同平臺下數據對齊性以及數據類型字節長度不同,結構體的長度在不同的平臺下字節值不同,因此在給出讀或寫的字節長度時,需使用操作符sizeof。
(2)double和longdouble對齊性不同:double和long double浮點變量的對齊方式不同可能導致接口問題。SPARC處理器double變量采用8字節對齊方式,x86處理器double變量采用4字節對齊方式。
(3)補位:由于不同平臺結構體中變量的對齊方式不同,引起補位不同,使結構體字節長度不同。編譯器在結構體中添加補位字節以使數據恰當對齊,補位字節長度與結構體、處理器和編譯器三者有關。
2.1.4 浮點操作不同
Solaris for X86系統浮點數80位寬,Solaris for SPARC系統浮點數是64位寬。由于位寬不同,算術運算的中間結構精度差異可能導致運算結果不同。在程序中加入-fstore編譯標志可以最小化差異,但使用-fstore標志會帶來運行效率的降低。
如前1.2所述,Solaris OS SPARC和Solaris OS x86的主要差別表現在兩個方面:
一是對專業圖形接口程序的支持方面。Solaris SPARC支持OpenGL,Solaris x86不支持OpenGL,為了實現移植建議圖庫使用MesaGL;二是某些特殊指令集不同,一些應用程序使用SPARC平臺上的特殊指令集來獲得綁定CPU的高性能事務。如使用快速傅立葉算法來處理語音識別和其他多媒體軟件的應用程序。這些應用程序從Solaris x86移植到SPARC平臺上時,需要找到可用于Solaris x86的替代算法。如可用MMX/SSE指令集 (多媒體指令集)來代替,該指令集可用于Solaris x86。
如前所述,Solaris SPARC和Solaris x86的差別主要表現在編譯器標志和線程本地存儲方面。
2.3.1 編譯器標志不同
Sun Studio編譯器包括C,C++編譯器。編譯器包括前端部分和后端部分。
前端部分包括源語言的語法和語義分析模塊,后端部分包括為特定硬件結構設置的代碼優化和代碼開發模塊。前端部分在SPARC和x86兩種平臺下是一樣的。后端部分依賴于平臺,在SPARC平臺和x86平臺下不同。Sun Studio編譯器對SPARC平臺和x86平臺的后端編譯器可提供不同的選項。當代碼從一種平臺移植到另一種平臺時,選擇可用的相同選項。為成功實現從SPARC平臺向x86平臺的移植,HP推薦使用Sun Studio8編譯器集。
2.3.2 線程本地存儲
線程本地存儲(TLS)是一種機制,經由它,程序可以擁有全局變量,但處于“每一線程各不相同”的狀態。在編譯時使用OS特定指令_thread可以聲明線程本地變量。在Solaris OS SPARC版本里邊,在代碼中全局變量初始化時添加_thread,該全局變量可被不同線程更改。Solari OSx86編譯器不支持具有_thread的代碼編譯。
在x86平臺上解決線程本地變量問題的方法是修改多線程共享全局變量處的代碼。可以使用POSIX和Solaris線程API調用來代替上述全局變量。
H9000系統是由標準C語言編寫的。由上述分析,要實現H9000系統從Solaris for SPARC系統到Solaris for x86系統的移植,需從硬件平臺、操作系統和編譯器三個方面分析考慮。
由前邊的分析,SPARC和x86硬件平臺的差異主要表現在字節順序、存儲順序、數據對齊性和浮點操作方面,結合前邊提到的由于這些差異導致的問題和相應的解決方式,H9000系統在進行平臺移植時應考慮:
(1)字節數的動態讀取;
(2)字節序列化的規范化程式;
(3)浮點操作使用-fstore flag,以保持計算精度,使平臺移植后結果差異最小;
(4)避免使用-xarch=v9 flag,造成可能的潛在錯誤。
H9000系統圖庫用gtk實現,因此不存在前邊所述的采用OpenGL所產生的移植問題。
考慮到部分特殊指令集平臺之間的不兼容性,將H9000系統中使用的特殊指令集全部由通用指令集替換。
由于SPARC和x86 Solaris的C編譯器不同,在進行選項配置的時候,編譯器flag的配置要選用既可用于SPARC平臺,又可用于x86平臺的flag。
[1]張凱龍,谷建華,等.Win32應用到Linux的跨平臺移植技術研究[J]. 微電子學與計算機,2004,21(11).
[2]Amjad Khan.Guide to Adding Support for SolarisOS on x86 Platform to Existing ApplicationsAvailable on SPARC Platform[Z].August 2003.
[3]王德寬,袁宏,等.H9000 V4.0計算機監控系統技術特點概要[J].水電自動化與大壩監測,2007,31(3):16-18.