将Linux C/C++应用程序从x86平台移植到IBM PowerLinux(5)
- UID
- 852722
|
将Linux C/C++应用程序从x86平台移植到IBM PowerLinux(5)
使用 IBM XL C/C++ 编译器进行移植
XL C/C++ 使用了 GNU C 和 C++ 头文件,而且结果应用程序被链接到 GCC 提供的 C 和 C++ 运行时库。这意味着 XL C/C++ 编译器生成了 GNU Executable and Linking Format (ELF) 对象,这些对象完全兼容 GCC 编译器生成的对象。XL C/C++ 包含对称多处理 (SMP) 运行时库,以便支持 XL C/C++ 的自动并行化和 OpenMP 特性。
从 GCC 移植到针对 Linux on Power 的 XL C/C++ 很简单。XL C/C++ 通过提供选项 -qinfo=por 来帮助完成此任务,帮助您过滤掉省略的诊断消息,进现实与可移植性问题相关的消息。此外,XL C/C++ 支持 gcc 和 gcc-c++ 的 GNU 扩展的一个子集。
请参阅 “XL C/C++ for Linux on pSeries 编译器参考”,了解受支持的特性的完整列表,以及那些被接受但拥有忽略了的语义的特性。
要对 C 代码使用受支持的特性,可以指定 -qlanglvl=extended 或 -qlanglvl=extc89。在 C++ 中,默认情况下会接受所有受支持的 GNU gcc/gcc-c++ 特性。此外,gxlc 和 gxlc++ 有助于最小化对使用 GCC 编译器构建的现有应用程序的 makefile 的更改
XL C/C++ 中的优化选项
XL C/C++ 提供了一些专门针对 IBM 硬件的优化选项。对于 Linux on Power,与使用 GCC 编译的应用程序相比,许多使用 XL C/C++ 并利用正确的优化标志组合而编译的应用程序都有巨大的性能改进。请注意,不是所有优化对所有应用程序都有利。通常,您需要在编译器完成的优化程度与编译时间的增加和调试能力的降低之间进行权衡。
优化级别
优化级别由编译器选项来指定。下表总结了每个优化级别上的编译器行为。
表 3. 每个优化级别上的编译器行为
选项 行为 -qnoopt 提供快速编译和完全调试支持。 -O2(与 -O 相同) 执行被编译器开发人员视为编译速度和运行时性能的最佳组合的优化。此设置会暗中使用 -qstrict 和 -qstrict_induction,除非使用
-qnostrict_induction 和 -qnostrict 进行明确否定。 -O3 执行更多内存密集型和/或编译时间密集型的优化。在运行时改进比最小化编译资源的利用更重要时,推荐执行这些优化。 -O4 和 -O5 执行过程间优化、循环优化和自动机器调优。 应避免的旧 Power 选项
从 x86 移植到 Linux on Power 时,来自旧 Power Architecture 的一些选项应避免使用且有害。
- 使用 -mminimal-toc 或 -mfull-toc 的 PPC64 构建版本应替换为 -mcmodel=medium(这是默认值)
- -ffloat-store,不会在 Power 上使用
目标机器选项告知编译器生成能够在给定微处理器或架构家族上最优地执行的代码。通过选择合适的目标机器选项,可通过优化来适应最广泛的目标处理器、给定处理器架构家族的许多处理器,或者一个特定的处理器。以下选项会控制影响目标机器的各个方面的优化:
表 4. 影响目标机器的各个方面的优化选项
选项 行为 -qarch 选择应针对其生成指令代码的一个处理器架构家族。默认值为 -qarch=auto。还提供了以下子选项:ppc64grsq、pwr3、pwr4、pwr5、ppc970、ppc64、ppcgr、rs64b 和 rs64c。 -qtune 针对在给定微处理器上执行而进行的基础优化,没有暗示要用作目标的指令集架构的任何信息。Linux 上的默认值为 -qtune=auto。可用的子选项包括:pwr3、pwr4、pwr5、pwr6、pwr7、pwr8、ppc970、rs64b 和 rs64c。但是,在许多情况下,此设置会基于 –qarch 的设置而自动设置。 -qcache 定义一种特定的缓存或内存几何结构。如果使用了 -qcache,则与它一起使用 -qhot 或 -qsmp。 -qhot 高阶转换属于专门通过交换 (interchange)、熔合 (fusion) 和展开 (unroll) 等技术来改善循环性能的优化。指定 -qhot 时,-qhot=vector 是默认选项。您可以尝试将 -qhot 与 -O2 和 -O3 结合使用。它的设计目标是在没有转换机会时产生一种中立效果。 -qsmp 生成共享内存并行处理所需的多线程代码。指定 -qsmp 时,-qsmp=auto 是默认选项。如果您在编译一个 OpenMP 程序且不想要自动并行化,那么可以使用 -qsmp=omp:noauto。使用 -qsmp 时始终使用 _r 编译器调用。 要最充分地利用目标机器选项,您应该:
- 使用 -qarch,指定您希望代码能在其上良好运行的最小的机器系列。
- 使用 -qtune,指定应具有最佳性能的机器。例如,如果将在基于 POWER8 处理器的系统及更高版本的系统的 Power 服务器上运行应用程序,那么可以使用 -O3 -qarch=pwr8 -qtune=pwr8。
IBM Power 平台支持其他平台上所没有的机器指令。XL C/C++ 提供了一组内置的函数,它们直接对应于某些 POWER 处理器指令。使用这些函数能消除函数调用-返回成本、参数传递、堆栈调整和所有其他与函数调用相关的成本。
但是,在使用 IBM XL C/C++ 编译器重新编译时,最初打算使用 GCC 编译器编译的软件可能需要更多地进行关注。您需要编辑 makefile 来反映 XL C/C++ 编译器的正确路径,该路径默认为 /opt/ibmcmp/。还需要设置针对特定架构的正确的优化标志(比如 -03 -qarch=pwr8 -qtune=pwr8 用于 IBM POWER8 处理器)。
除了针对各种 Power Architecture 衍生产品的优化模式,还可以告诉 XL C/C++ 编译器在通用模式下编译软件。这可以确保跨所有 Power Architecture 衍生产品的兼容性,但会牺牲通过特定于架构的优化所获得的性能优势。在编译 64 位代码时,必须为编译器提供针对 64 位构建版本的标志(即 -q64),因为它在默认情况下为 32 位模式。
下面列出了使用 XL C/C++ 编译器编译面向 GCC 的代码的一些技巧:
- 在默认情况下,GCC 允许在 C 文件中使用 C++ 风格的注释,但这不适合 XL C 编译器 XLC。因为更改一组源文件中的所有注释来遵守 C 风格的注释格式不太合算,所以 XLC 提供了一个 -q 参数来允许使用这些注释:-q cpluscmt。在使用此标志编译 C 代码时,会解释 C 和 C++ 风格的注释。
- 环境变量常常是配置构建脚本的最简单的方式。无需手动编辑配置脚本和 makefile,您应该设置相关的环境变量,比如 $CC 和 $CFLAGS,以便允许通过配置脚本来生成 makefile,而无需手动编辑。
- 配置脚本还需要知道正确的平台类型。平台类型将为 linux-powerpc-unknown-gnu 或 linux-powerpc64-unknown-gnu。您应该通过将 -target=标志被附加到配置脚本中,为使用 GCC 或 XL C/C++ 的编译设置此平台类型。
- 尽管 IBM XL C/C++ 编译器有许多文档,您仍然可以运行该编译器而不使用参数在控制台显示参数列表,例如 $COMPILER_PATH/bin/cc。
编译器选项比较
下表比较了来自 GCC 和 XL C/C++ 的常用编译器选项。
表 5. 来自 GCC 和 XL C/C++ 的常用编译器选项
GCC XL C/C++ 描述 -v -v、-V、-# 打开详细模式。 -p/-profile -p 设置编译器生成的对象文件,以进行分析。 -m32、-m64 -q32、-q64,或者设置 OBJECT_MODE 环境变量 创建 32 或 64 位对象 -fsyntax-only -qsyntaxonly 执行语法检查而不生成对象文件。 -fpic -qpic=small 生成与位置无关的代码,以便在共享库中使用它们。在 XL C/C++ 中,全局偏移表的大小不大于 64 KB。如果指定了 -qpic 而没有任何子选项,则假设使用了 -qpic=small。如果指定了 -qmkshrobj 编译器选项,则会启用 -qpic 选项。 -fPIC -qpic=large 允许全局偏移表大于 64 KB。 -pthread -qthreaded 或 _r invocation 模式 创建在多线程环境中运行的程序。 -fno-rtti -qnortti 禁止生成运行时类型标识 (RTTI) -qrtti 来进行异常处理,并且禁止 typeid 和 dynamic_cast运算符使用 RTTI。在 XL C/C++ 上,默认选项为 -qnortti。 -static -qstaticlink 阻止此选项生成的对象与共享库链接。 -static-libgcc -qstaticlink=libgcc 告诉编译器与 libgcc 的静态版本链接。 -shared -qmkshrobj 告诉编译器生成一个共享对象。 -shared-libgcc -qnostaticlink=libgcc 告诉编译器与 libgcc 的共享版本链接。 -Wl、-rpath -Wl、-rpath 或 -R 传递一个冒号分隔的目录列表,用它来指定一个运行时链接所搜索的目录。 -fno-implicit-templates、-frepo -qtempinc、-qtemplateregistry、-qtemplaterecompile 实例化模板。 -w -w 禁止警告消息。 -warn64 启用对长整型到整型的截断操作的检查。 -qinfo=< > 生成包含信息的消息。 -fpack-struct -qalign=bit_packed 使用 bit_packed 对齐规则。 -qalign=linuxppc 使用默认 GCC 对齐规则保持与 GCC 对象的兼容性。这是默认设置。 -O、-O2、-O3 -O、-O2、-O3、-O4、-O5 用于设置优化级别。 Ofast、Og Ofast – 提供速度优化,不完全符合标准
Og – 提供优化,但允许在需要时执行一些有效的调试。 -mcpu、-mtune -qarch、-qtune、-qcache 用于设置一个特定处理器的优化选项。 使用 GCC 构建大型程序
客户有时需要构建一个在运行时生成的非常大的可执行文件。清单 5 中给出了一条常见的错误消息。
清单 5. 构建大型可执行文件时的错误消息
modelfile.cxx.o.text+0x212012): relocation truncated to fit: R_PPC64_TOC16_DS against `.toc'+10000 这是大型程序和旧 GCC 编译器的一个常见问题。旧 GCC 编译器乐观地假设目录 (table of contents, TOC) 不会溢出单个加载指令的 64 KB 范围。在这种情况下,该程序很大,需要的所有 TOC 条目的总和超过 16 位 (TOC16_DS)。
有两个解决方案。
- 对于 Advance Toolchain 3.0 和旧编译器,可以使用 -mminimal-toc 进行重新编译。
- 对于 Advance Toolchain 4.0 和更高版本的编译器,可以使用 -mcmodel=medium 进行重新编译。-mcmodel=medium 应具有更好的性能,但需要升级。
|
|
|
|
|
|