从Windows到Linux的C程序移植研究
2018-07-10夏永红匡华星
蒋 跃,田 田,夏永红,匡华星
(中国船舶重工集团公司第七二四研究所,南京 211153)
0 引 言
当前,作为舰艇平台发展的革命性技术之一的“高性能公共计算环境”已经得到了越来越多的关注。作为下一代舰船的信息整合与处理中心,通过“高性能公共计算环境”可以对平台内的所有资源(包括射频资源、面阵资源、信息处理资源等)进行统一任务调度和联合资源分配,以充分发挥系统整体资源优势。
由于具有高效性、稳定性、安全性等特点[1],Linux系统更适合于作为“高性能公共计算环境”的操作系统。美国的DDG-1000全舰计算环境就采用了刀片服务器架构,操作系统为Red Hat Linux。国内的中标麒麟桌面操作系统采用强化的Linux内核,实现对X86及国产CPU平台的全面兼容。基于上述原因,开展了基于Linux操作系统开发环境的雷达全流程仿真软件开发和仿真试验,为雷达信息处理应用在Linux操作系统上的开发实现积累经验。本文针对从Windows到Linux的C程序移植,介绍了Linux系统的安装和开发环境的搭建,并探讨了C程序移植的方法和经验。
1 Linux系统安装和开发环境搭建
1.1 Linux系统安装
在现有的Windows系统下安装Linux系统有两种方式可以选择:一是一般安装,即分配单独的硬盘分区用来安装Linux系统;二是虚拟机安装,即使用软件模拟一个具有完整硬件系统功能的计算机并安装Linux系统。一般安装可以实现计算机的双系统,但在使用时只能选择进入一种操作系统。而虚拟机安装则能保证新系统在一个完全隔离的环境中工作,虚拟机中安装和运行的应用程序就像在真正的计算机上一样。[2]同时,对于Windows用户来说,虚拟机只是物理计算机上的应用程序,即使虚拟机中安装的系统发生崩溃也不会影响物理计算机上的Windows系统。更重要的是,虚拟机安装可以实现Windows系统与Linux系统下资源的拷贝共享,有需要的话完全可以在物理计算机上模拟多台虚拟的计算机,并且安装好的虚拟机也可以拷贝到其他物理计算机上使用。因此,本文选择使用虚拟机在现有Windows系统下安装Linux操作系统。
在当前的主流虚拟机软件中,VMware在多操作系统支持和执行效率上都具有比较明显的优势,因此本文选择VMware软件来创建虚拟机。本文所使用的虚拟机安装了CentOS 7版本的Linux操作系统。安装完成后在Windows系统下只需要打开VMware软件,启动虚拟机即可登录CentOS 7,实现Windows与Linux系统的同时工作。在VMware软件中还自带了一种增强工具VMware Tools,可以实现物理计算机(Windows)和虚拟机(Linux)或者两台虚拟机之间的拷贝功能,方便资源共享和用户使用。
1.2 开发环境搭建
Eclipse[3]是一个开源免费的基于Java撰写的集成开发环境(IDE),提供图形化的编辑和调试界面,可以跨平台,在Windows和Linux系统下都可以使用。另外,Eclipse本身是可扩展的开发平台,通过插件可以实现目前主流程序语言诸如C/C++、C#、Java、PHP、Python等等的程序开发。因此,本文选择在Linux系统下安装Eclipse来进行C/C++的程序开发。
Eclipse开发程序的流程一般为创建工程->创建文件->编辑文件->编译工程->运行或调试。由于本文是将Windows系统下的C程序移植到Linux系统中,在创建工程后只需将编辑好的各个工程文件导入即可,再对工程进行编译、运行或调试。
2 C程序移植方法
在将C程序从Windows系统移植到Linux系统的过程中,由于Linux下gcc默认的编译规则是比VC严格的,在VC中编译通过的程序放到Linux下却可能出现许多警告错误[4]。根据实际的C程序移植经验,在移植过程中需要注意以下几方面:
(1) 确保文件名的大小写正确
虽然在C/C++语言中是区分大小写的,但对于程序中包含的头文件,在Windows系统下其文件名大小写都可以正确编译,而在Linux系统下却必须要头文件的大小写正确。这是由于ext2文件系统对文件名的大小写敏感,避免在编译中出现找不到头文件的错误。
(2) 注意各个系统下独有的头文件
在Windows系统下,程序中通常会包含头文件“windows.h”,若程序需要实现网络通信,则需包含头文件“winsock2.h”或者MFC下的“afxsock.h”。这些头文件都是Windows系统独有的。因此,程序在移植到Linux系统后,需要将这类头文件以及一些Windows系统的常量定义说明注释掉,并且添加Linux系统下对应的头文件,例如头文件“sys/socket.h”即可支持实现网络通信。
(3) 注意VC中独有的数据类型和关键字
VC中__int16、__int32、__int64等独有的数据类型在Linux系统中编译器并不支持,无法正确识别这些数据类型。因此,在程序移植后可以将这些数据类型在VC中的定义语句复制到一个头文件中,并在程序中包含该头文件。而对于VC中独有的关键字如WORD、DWORD、__asm等等,应尽量避免在程序中使用,或者在移植后用“#ifdef”和“#endif”重新编写。因此,为提高程序在不同平台之间的可移植性,在程序编写过程中应该避免直接使用各编译器独有的数据类型或关键字。
(4) 注意修改相应函数原型
对于程序中使用标准C/C++语言编写的函数,在不同系统下基本都可以适用。但是,对于一些系统调用函数,由于Linux与Windows有所区别,需要改变相应的函数原型。例如,要实现网络通信功能,在Windows中使用MFC下CSocket编程,调用CSocket::Create初始化、CSocket::Bind绑定地址端口、CSocket::SendTo发送内容、CSocket::Close关闭等等,而在Linux中相应地通过socket、bind、sendto、close等函数实现这些功能。若要实现文件指针的移动,在Linux中用fseeko64函数代替Windows下的_fseeki64函数来将文件指针移动到指定的位置。在计算程序运行耗时方面,Windows系统使用QueryPerformanceFrequency和QueryPerformanceCounter函数来计时,而Linux系统下则可以用gettimeofday函数实现计时功能。因此,在程序移植中要实现相同的功能需要改变相应的函数原型。
(5) 注意编译环境的配置
在Windows系统中,使用VC编写的工程需要添加头文件引用路径以及库文件的引用路径和链接。相应地,在Linux系统中也要对Eclipse的编译环境进行配置。由于在程序中采用了Intel IPP函数库进行加速计算,并且在VC中利用IPP的多线程静态函数库进行内部并行加速,在程序移植后也需要进行修改配置。因此,在Linux系统中需要先安装相应版本的Intel IPP,并且在Eclipse中修改工程属性,配置IPP的环境变量、头文件引用路径、库文件引用路径和链接。在配置完编译环境可以正确编译后,还需要在运行或调试配置中也相应配置IPP的环境变量。
(6) 注意系统文件或路径
在Windows与Linux系统中,各自的路径标识符是不同的,因此程序移植后需将路径中的“\”改为“/”。另外,由于Linux系统中对于文件或者目录的权限是分为拥有者、群组和其他的,在对文件进行写操作时需要注意修改文件或目录的权限,否则无法进行写操作。
以上几方面仅是实际C程序移植过程中出现的需要注意的问题。但是,在具体的程序移植过程中可能还会出现更多更复杂的情况,例如移植Windows系统下用MFC编写的图形界面程序、多进/线程程序等等都还需要分析程序设计结构,理解程序逻辑模块,才能更好地完成程序移植。
3 移植结果分析
某型雷达的全流程处理程序原是在Windows系统的VC中实现的,本文将其移植到Linux系统,程序成功编译并运行,输出结果与VC程序保持一致,成功完成移植工作。本文所使用的物理计算机为Windows系统,内存为32 GB,处理器为i7-6700K 四核八线程;而创建的虚拟机为Linux系统,内存为4 GB,处理器为双核。由于全流程处理程序运行所需内存占比较小,且程序内部仅利用双核进行并行加速,处理结果基本不受两个系统环境的计算资源影响。下面对两个系统下程序各功能模块的处理耗时结果进行对比分析,对比结果如表1所示。
表1 两个系统下程序各功能模块处理耗时对比
从表1中可以看出,在读取数据上Linux系统耗时减少了约20 s,查找包头两者耗时差不多,信号处理部分Linux耗时减少了约7 s。虽然在点迹凝聚时Linux耗时多了近5 s,但在发送和记录点迹以及输出和发送视频方面则有了较大提升,耗时节省了约33 s。统计整个程序所有功能模块的处理时间,Linux系统的耗时比Windows节约了56 s。这是由于Linux系统简单、占用内存少,可以利用最少的资源最短的时间实现所有功能,而且Linux系统在硬件支持和网络性能方面较Windows都占优势。
表2给出了信号处理中各功能模块的处理耗时对比。从中可以发现,两个系统下信号处理的各功能模块的合计耗时与表1中基本相符,且在脉冲压缩部分Linux的耗时减少更为明显。
表2 两个系统下信号处理各功能模块处理耗时对比
4 结束语
本文针对从Windows到Linux的C程序移植,介绍了Linux系统的安装和开发环境的搭建,根据实际程序移植经验给出了C程序移植的方法和需要注意的问题,同时对实际程序各功能模块的处理耗时结果进行了对比分析,程序在Linux系统下耗时更短。