白剑飞,文正国
(中国水利水电科学研究院中水科技公司,北京 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.