将Linux C/C++应用程序从x86平台移植到IBM PowerLinux(5)
- UID
- 1029342
- 性别
- 男
|
将Linux C/C++应用程序从x86平台移植到IBM PowerLinux(5)
Linux Cross-platform Tool (LCT)
SDK for PowerLinux 还提供了另一个可以在任何现有的 Intel x86 平台上运行的方便工具。它是一个命令行工具,用于识别应用程序的潜在可移植性。这样,在移植到 Linux on Power 之前,您能够快速了解源代码中的潜在问题。在安装 IBM SDK for PowerLinux 后,可以在该工具的 README 部分中找到 LCT 文档。
IBM Rational Developer for Power Systems
IBM Rational Developer for Power Systems 也提供了一个富桌面集成开发、移植和优化环境,用于多平台开发(IBM i、AIX 或 Linux on Power)。它的特性还包括各种移植工具,比如 Code Analysis 工具、Performance Advisor 工具和 Migration Assistant,类似于 IBM SDK for PowerLinux,这些工具可以检测 32 位到 64 位迁移问题、字节顺序问题,以及其他可能阻碍移植的操作系统问题。
JVM
Java 虚拟机 (JVM) 在所有平台上都以高位优先模式运行,因此常常对处理器架构带来的影响免疫。
数据类型和对齐方式
应用程序二进制接口 (ABI) 中重要的 有符号/无符号字符 细微差异。
在 x86/x86_64 下,“char” 的默认值为 “signed char”,而 Power Systems 上的默认值为 “unsigned char”。在 Power Systems 上,可以使用 GCC 指令 -fsigned-char 覆盖该默认值。等效的 IBM XL 指令为 -qchars=signed。
Linux 操作系统上的 GCC 和 XL C/C++ 编译器都提供了两种不同的编程模型:ILP32 和 LP64。ILP32 表示 Integer Long Pointer 32,是 Linux 上原生的 32 位编程环境。ILP32 数据模型提供了一个 32 位地址空间,它的理论内存被限制为 4 GB。LP64 表示 Long Pointer 64,是 Linux 上的 64 位编程环境。
表 1 显示了 POWER 和 x86 平台上的 ILP32 和 LP64 模型中的基础数据类型中的位宽。
表 1. POWER 和 x86 平台上的 ILP32 和 LP64 模型中的基础数据类型(位)
基础数据类型 POWER x86 ILP32 ILP64 ILP32 ILP64 char
默认值:x86 上为 signed - POWER 上为 unsigned 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 指针 32 64 32 64 *Linux on Power 上的 long double 的默认大小现在为 128 位。如果使用编译器选项 -qnoldb128 和 XL C/C++ 编译器,那么它们可以减少到 64 位。
在 Power 和 x86 平台上的 /usr/include/limits.h 中,可以找到数字值的所有定义。
许多遗留 Linux x86 应用程序在 32 位下运行。对于最新的 x86 架构(支持并鼓励采用 64 位应用程序),更多的 x86 应用程序是在 64 位模式下原生地更新或编写的。在将 x86 应用程序移植到 Power Systems 的练习中,可采用 Linux on Power 环境作为目标来匹配您的来源环境。换句话说,我们推荐首先完成初始移植,然后再考虑移植到 64 位编程模型。如果希望将 32 位 x86 应用程序移植到 64 位 Power Systems 编程模型,那么可以将迁移分为两步:
- 移植到 Linux on Power 32 位环境(包括测试和验证它)。
- 然后迁移到 64 位环境。
如果应用程序满足以下条件:那么工程师应考虑将应用程序移植到 64 位:
- 能从超过 4GB 的虚拟地址空间受益
- 能够从更多物理内存(大于 4GB)受益,以及用户可能将它部署在具有超过 4GB 物理内存的系统上
- 能够从 64 位大小的长整数受益
- 能够使用完整的 64 位寄存器来执行高效的 64 位算法
- 使用大于 2GB 的文件
一些可通过迁移到 64 位而受益的应用程序示例包括:
- 数据库应用程序,尤其是执行数据挖掘的应用程序
- Web 缓存和 Web 搜索引擎
- 计算机辅助设计 (CAD)/计算机辅助工程 (CAE) 模拟和建模工具的组件
- 科学和技术计算应用程序,比如计算流体动力学、遗传模拟等
应用程序可保留 32 位并仍在 64 位 Linux on Power 内核上运行,无需任何代码更改。基于 IBM Power 处理器的服务器支持 32 位和 64 位应用程序同时在 64 位架构上运行
在不同平台(从 x86 到 Power)或编程模型(从 ILP32 到 LP64)之间移植应用程序时,需要考虑不同环境中提供的数据宽度和对齐设置之间的差异,以避免可能的性能降级和数据损坏。
在从 x86 ILP32 移植到 POWER ILP32 或从 x86 LP64 移植到 POWER LP64 时,您可能注意到,在表 1 中,所有基本数据类型的宽度都保持相同,除了 long double 96 位变为 IPL32 上的 64/128 位,128 位变为 LP64 上的 64/128 位。这意味着您应该检查与 long double 数据类型相关的代码部分。如果计划使用 XL C/C++ 编译器,那么可以使用 -qlongdouble 编译标志在 long double 数据类型上实现最高的兼容性。
数据对齐
在平台之间或 32 位与 64 位模型之间移植应用程序时,需要考虑不同环境中提供的对齐设置之间的差异,以避免可能的性能降级和数据损坏。最佳实践是对数据项执行自然对齐。自然对齐表示将数据项存储在是其大小的倍数的地址上(例如,8 字节数据项存储在一个为 8 的倍数的地址中)。对于 XL C/C++ 编译器,依据 linuxppc 或位包装规则,聚合中的每种数据类型(C/C++ 结构/union 和 C++ 类)将与字节边界对齐,其中 linuxppc 是默认规则,这是一种自然对齐方式。linuxppc 也兼容默认的 GCC 对齐规则。表 2 显示了 POWER 和 x86 上的对齐规则,以及它们的数据类型宽度(以字节为单位)。
表 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 指针 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 Systems 上与 8 字节对齐。因此,不同平台上的结构将具有不同的布局。不要硬编码任何大小和偏移,这很重要。相反,您应该使用 C 运算符 sizeof 来查询基础和复杂类型的大小。宏 offsetof 可用于从结构开头获取结构成员的偏移。
确定要使用哪个编译器:GCC 或 IBM XL C/C++
有两个 C/C++ 编译器可用于 Linux on Power:GCC 和 IBM XL C/C++ 编译器。GCC 针对 Linux 上的编译提供了可靠的代码移植功能,而在使用更高级的优化时,与 GCC 相比,IBM XL 编译器显著提升了性能。两种编译器都提供了 32 位和 64 位编译模式,Linux on Power 环境支持在不降低性能的情况下同时运行 32 位和 64 位代码。 |
|
|
|
|
|