Red Hat® Enterprise Linux® 5.3 基于 Linux 2.6.18 内核并提供 GCC 4.1.2、glibc 2.5 和 binutils 2.17。相对以前的版本而言,RHEL5 包含许多改进。这些改进包括可切换的动态 I/O 调试器、IPv4/IPv6 性能改进,以及改善了可伸缩性和性能的内核 SMP 锁改进。
Red Hat Enterprise Linux 4.8 基于 Linux 2.6.9 内核并提供 GCC 3.4.6、glibc 2.3.4 和 binutils 2.15。不过,GCC4 包被更新到版本 4.1.2。(参考资料 部分提供一个文章链接,该文章在受支持的平台上对比了 RHEL3、RHEL4 和 RHEL5 的特性)。
与 Solaris 相似,除 GNU Compiler Collection 之外,Linux on POWER 还提供了高性能编译器集合 —— IBM XL C/C++ 编译器集合。XL C/C++ Advanced Edition for Linux Web 站点中有关于其许可证的详细信息。(参考资料 部分提供相关链接)。下面简单概述每组编译器及其优势:
- GCC
对于跨多个平台开发的项目(其中 GCC 编译器为原始编译器),经常使用 GCC 编译器来部署 Linux on POWER 的应用程序。对于性能不是至关重要的应用程序尤其如此;例如,一些小的实用程序。GCC 还允许使用一些只有 GCC 才理解的代码原型,比如 GCC 特定宏。然而,IBM XL C/C++ 编译器中合并了其中许多 “GCC-isms”。 - Advance Toolchain
对于能够利用最新 GCC 和工具链技术的项目,希望继续使用 GCC 编译器的客户可以使用 Advance Toolchain 包。Advance Toolchain 提供更新的 GCC 编译器版本,并在使用 SLES10 和 RHEL5 时针对 Power 6 调用了运行时库。在许多情况下,对于利用在 -O3 编译级别上进行编译的 Advance Toolchain 的 GCC 编译应用程序,其性能接近于在 -O3 级别上进行编译的 IBM C/C++ 编译器。IBM 编译器的优势是性能改进和调优存在比较大的空间,这在某些情况下尤为有用。 - XL C/C++
针对 Power 系统的 IBM Linux XL C/C++ 编译器已经可用。针对 RHEL5、SLES10 和 SLES11 的 XL C/C++ 编译器 10.1 版本已经可用。如果您希望在更旧的 Linux 发行版(比如 SLES 9、SLES10 sp1、RHEL5 或 RHEL 4)上进行构建,IBM 编译器的以前版本(比如 XL C/C++ 版本 8 和 9)仍然可用。XL C/C++ 编译器提供 GCC 的高性能代替品,以及许多其他特性。幸运的是,XL C/C++ 编译器生成 32 位和 64 位 GNU elf 对象,它们与 GCC 编译器生成的对象完全兼容,因为 XL C/C++ 编译器使用与 GCC 相同的 GNU 库、连接程序、汇编程序和 binutil。实际上,以前专门由 GCC 编译器提供的功能已经移植到 XL C/C++,以促进源代码兼容性;例如,一些 GCC 宏和在线功能。但是除了兼容性,XL C/C++ 还提供了无可匹敌的性能。
已经为 POWER 架构开发并修改了成熟的 XL C/C++ 优化例程并且收到了预期效果。通常对于高性能计算应用程序,尤其是那些高度依赖浮点操作的应用程序,使用 XL C/C++ 进行重新编译会很有好处。
虽然 XL C/C++ for Linux on POWER 不是免费的,然而开发人员可以免费试用 60 天。详细信息请访问 XL C/C++ for Linux Web 站点(参考资料 部分提供相关链接)。 - XL Fortran
如果您希望使用 Fortran 的话,针对 Power 系统的 IBM XL Fortran 已经可用。针对 RHEL5、SLES10 和 SLES11 的 XL Fortran 版本 11.1 和 XL Fortran 版本 12.1 已经可用。详细信息请访问 XL Fortran for Linux Web 站点(参考资料 部分提供相关链接)。
在 Solaris 10 中,可以选择使用原生构建实用程序或使用随 GNU 一起提供的实用程序。通过 Linux on POWER,GNU binutil 用于使用 XL C/C++ 编译器集合和 GCC 来生成对象。GNU Binutils 站点中非常详细地讲述了 GNU binutil。(参考资料 部分提供相关链接)。
如果 Java Runtime Environment 与开发软件平台的 Java Developer Kit (JDK) 兼容,Java 技术允许开发人员跨多个平台进行部署,而不用重新编译代码。通过 IBM Developer Kit for Linux, Java Technology Edition 版本 1.4.2、5.0 和 6.0,RHEL4、RHEL5、SLES9、SLES10 和 SLES11 都支持 Linux on POWER Java 开发。这一套开发人员套件有 32 位版本和 64 位版本,可从 IBM 免费下载(见 参考资料)。
Solaris 和 Linux on POWER 之间的差别
在这一节中,将了解 Solaris 与 Linux on POWER 之间的差别,其中包括系统调用、信号、数据类型、makefile、编译器选项、连接程序选项和线程库等。
系统调用是用户程序使用的接口,它可以使内核代表调用线程或进程执行特定函数。要执行系统调用,还需要授权内核模式的上下文切换。库函数是普通 C 函数。它们没有任何上下文切换资源损耗,因为它们是使用其每个进程的地址空间的一部分。一些 Solaris 系统调用和库函数可能不能用于 Linux 中。发生这种情况时,可能要在 Linux 中实现打包器调用。
Linux on POWER 目前提供了 300 多种不同的系统调用。/usr/include/asm-powerpc/unistd.h 或 /usr/include/asm/unistd.h 中包含系统调用列表,具体目录取决于您使用的发行版。
下面是 Solaris 和 Linux 之间不兼容的一些例子:
- regexp() 和 regcmp():如果您在 Solaris 上使用 regexp() 和 regcmp(),则在 Linux 上需要将它们替换为 regexec() 和 regcomp()。
- 文件系统接口例程:Solaris 文件系统例程使用 vfstab 结构,函数名中包含 vfs,比如 getvfsent。Linux 提供等同的接口,但是例程使用 fstab 结构,例程名称中包含 fs,比如 getfsent。Solaris 中的 vfstab 结构是在 /usr/include/sys/vfstab.h 中定义的。Linux 中的 fstab 则是在 /usr/include/fstab.h 中定义的。
- Device Information Library Functions (libdevinfo):libdevinfo 库包含一组接口,用于访问设备配置数据,如主号码和辅助号码。标准 Linux 安装不支持这一点。
- CPU Affinity:在默认情况下,多处理器系统中的进程在多个 CPU 之间切换。在某些情况下,通过明确地将进程绑定到特定 CPU(分配 CPU 亲和力)可以提高性能。Solaris 中 CPU 亲和力的系统调用与 Linux 中的不同。Linux 2.6 内核为 CPU 亲和力提供了 sched_setaffinity() 和 sched_getaffinity()。有关的详细信息,请参阅 Linux 手册。
表 1 列出了 Solaris 系统调用,这些系统调用与 Linux 中系统调用的名称、签名不同,或在 Linux 中不可用:
Solaris | Linux | 说明 |
---|---|---|
acl、facl | N/A | 获取或设置文件的 Access Control List (ACL) |
adjtime | N/A | 更正时间,以允许系统时钟同步 |
audit | N/A | 向审计日志写入记录 |
auditon | N/A | 对审计进行操作 |
auditsvc | N/A | 向特定文件描述符写入审计日志 |
getacct、putacct、wracct | N/A | 获取、放入或写入扩展报告数据 |
getaudit、setaudit、getaudit_addr、setaudit_addr | N/A | 获取和设置进程审计信息 |
getauid、setauid | N/A | 获取和设置用户审计身份 |
getdents | getdents** | 读取目录条目,并以单独格式将其放入文件系统中。Linux 中的 Dirent 结构与 Solaris 中的不同 |
getmsg、getpmsg | N/A | 获取数据流中的下一条消息 |
getpflags、setpflags | N/A | 获取或设置流程标记 |
getppriv、setppriv | N/A | 获取或设置进程标志 |
getustack、setustack | N/A | 检索或更改 per-LWP 堆栈边界信息 |
issetugid | N/A | 确定当前可执行程序是在运行 setuid 还是在运行 setgid |
llseek | _llseek | 移动扩展读/写文件指针 |
_lwp_cond_signal、_lwp_cond_broadcast | N/A | 对条件变量发送信号 |
_lwp_cond_wait、_lwp_cond_timedwait、_lwp_cond_reltimedwaid | N/A | 等待条件变量 |
_lwp_info | N/A | 返回单个 LWP 的时间核算信息 |
_lwp_kill | N/A | 向 LWP 发送信号 |
_lwp_mutex_lock、_lwp_mutex_unlock、_lwp_mutex_trylock | N/A | 互斥 |
_lwp_self | N/A | 获取 LWP 标识符 |
_lwp_sema_wait、_lwp_sema_trywait、_lwp_sema_init、_lwp_sema_post | N/A | 信号灯操作 |
_lwp_suspend、_lwp_continue | N/A | 继续或暂停 LWP 执行 |
memcntl | N/A | 内存管理控制 |
meminfo | N/A | 提供内存信息 |
mount | mount* | 装载文件系统。Solaris 中此系统调用的签名与 Linux 的不同 |
msgids | N/A | 发现所有消息队列标识符 |
msgrcv | msgrcv* | 消息接收操作。Linux 在其一个参数中使用 struct msgbuf 类型 |
msgsnap | N/A | 消息队列快照操作 |
msgsnd | msgsnd* | 消息发送操作。Linux 在其一个参数中使用 struct msgbuf 类型 |
ntp_adjtime | N/A | 调整本地时钟参数 |
ntp_gettime | N/A | 获取本地时钟值 |
open、openat | open* | 打开文件。openat() 不能在 Linux 中使用 |
pcsample | N/A | 程序执行时间配置文件 |
p_online | N/A | 返回或更改处理器操作状态 |
priocntl | N/A | 进程调度器控制 |
priocntlset | N/A | 一般化的进程调度器控制 |
processor_bind | sched_setaffinity | 将 LWP 绑定到处理器 |
processor_info | N/A | 确定处理器类型和状态 |
pset_bind | N/A | 将 LWP 绑定到处理器集合 |
pset_create、pset_destroy、pset_assign | N/A | 管理处理器集合 |
pset_info | N/A | 获取处理器集合的信息 |
pset_list | N/A | 获取处理器集合的列表 |
pset_setattr、pset_getattr | N/A | 设置或获取处理器集合属性 |
putmsg、putpmsg | N/A | 发送流消息 |
rename、renameat | rename* | 更改文件名。Linux 没有 renameat() 函数 |
resolvepath | N/A | 分析路径名称的所有符号链接 |
semids | N/A | 发现所有信号灯标识符 |
setrctl、getrctl | N/A | 设置或获取资源控制值 |
settaskid、gettaskid、getprojid | N/A | 设置或获取任务或项目 ID |
shmids | N/A | 发现所有共享内存标识符 |
sigsend、sigsendset | N/A | 向处理器或处理器组发送信号 |
__sparc_utrap_install | N/A | 安装 SPARC V9 用户陷阱处理程序 |
fstatat | N/A | 获取文件状态 |
swapctl | N/A | 管理交换空间 |
uadmin | N/A | 管理控制 |
unlink、unlinkat | unlink* | 删除目录条目。Linux 没有 unlinkat() 函数 |
futimesat | N/A | 设置文件访问权和修改时间。它分析关于 fildes 参数的路径 |
waitid | N/A | 等待子进程来更改状态 |
yield | sched_yield | 放弃对其他轻量级进程的执行 |