Sun Studio 12:Fortran 编程指南

9.1.1 性能选项

下表列出的编译器选项为用户提供了在缺省编译之上提高程序性能的一整套策略。表中只列出了更加有效的编译器性能选项中的一些选项。更完整的列表见《Fortran 用户指南》。

表 9–1 一些有效性能选项

操作 

选项 

同时使用优化选项组合 

-fast

将编译器优化级别设置为 n

-On (-O = -O3)

指定通用目标硬件 

-xtarget=sys

指定特殊指令集架构 

-xarch=isa

使用性能配置文件数据进行优化(使用 -O5

-xprofile=use

n 值展开循环

-unroll=n

允许简化和优化浮点 

-fsimple=1|2

执行依赖性分析以优化循环 

-depend

执行过程间优化 

-xipo

这些选项中的某些选项会增加编译时间,因为它们会调用更深层的程序分析。当例程与其调用例程被一起收入文件中(而不是将每个例程分割到自己的文件中)时,一些选项工作效果最佳;这样做将允许进行全局分析。

9.1.1.1 -fast

此单个选项会选用许多性能选项。


注 –

该选项定义为其他选项的特殊选择集,它会随版本和编译器的不同而变化。另外,-fast 选用的某些选项可能不是在所有平台上都可用。使用 -dryrun 标志进行编译可查看 -fast 的扩展。


-fast 可为某些基准测试应用程序提供高性能。但是,对于您的应用程序,选项的特定选择可能是合适的,也可能是不合适的。使用 -fast 是编译应用程序以获得最佳性能的良好起点。但是,仍然可能需要进行其他调整。如果用 -fast 编译时程序不能正常运行,请仔细查看组成 -fast 的各个选项,只调用那些适用于您程序的选项,使程序正常运行。

另请注意,用 -fast 编译的程序对于一些数据集可能会表现出良好的性能和精确的结果,而对于另一些数据集则不然。对于那些依赖浮点运算的特殊属性的程序,请避免用 -fast 进行编译。

由于 -fast 选择的某些选项具有链接含义,因此,如果在不同的步骤中进行编译和链接,还请务必用 -fast 进行链接。

–fast 会选用以下选项:

-fast 为运用编译器的诸多强大优化能力提供了一条捷径。可以单独指定复合选项中的每一个,并且每一选项都可能具有副作用,对此应引起注意(有关论述见《Fortran 用户指南)。另请注意,-fast 的确切展开形式可能会随各个编译器发行版本而发生改变。使用 -dryrun 进行编译会显示所有命令行标志的展开形式。

-fast 一起使用其他选项可进一步增加优化。例如:

f95 -fast -m64 ...

可对启用了 64 位的平台进行编译。

由于 -fast 会调用 -dalign-fns-fsimple=2,因此用 -fast 编译的程序会导致非标准浮点运算、非标准数据对齐以及非标准表达式求值顺序。对于大多数程序来说,这些选择可能是不合适的。

9.1.1.2 -On

除非显式指定 -O 选项(或使用类似 -fast 的宏选项隐式指定),否则编译器不会执行任何优化。几乎在所有情况下,在编译时指定优化级别都会提高程序执行性能。另一方面,优化级别越高编译时间就越长,并有可能显著增加代码长度。

对于大多数情况,采用 -O3 级别可在性能增益、代码长度和编译时间之间取得良好的平衡。-O4 级别将同一源文件中所含例程调用的自动内联添加作为调用者例程,除此之外它还会做一些其他事情。(有关子程序调用内联的进一步信息,参见《Fortran 用户指南》。)

-O5 级别会增添更多积极主动的优化技术,这些技术在更低级别不适用。一般而言,仅对于那些构成程序计算强度最高部分并因此而具有较高性能提高余地的例程,才应为其指定 -O3 以上的级别。(将用不同优化级别编译的程序部分链接起来,不存在任何问题。)

9.1.1.3 PRAGMA OPT=n

使用 C$ PRAGMA SUN OPT=n 指令可为一个源文件中的各个例程设置不同的优化级别。该指令将覆盖编译器命令行中的 -On 标志,但必须与 -xmaxopt=n 标志一起使用,才可设置最高优化级别。有关详细信息,参见 f95(1) 手册页。

9.1.1.4 利用运行时配置文件反馈信息进行优化

当编译器O3 及更高级别应用其优化策略时,如果结合使用 -xprofile=use,将会大大提高效率。利用该选项,可以通过具有典型输入数据的程序(用 -xprofile=collect 编译)所产生的运行时执行配置文件来指导优化器。反馈配置文件会为编译器指出在哪里优化将会获得最大效果。这对于 -O5 选项可能尤为重要。下面给出了一个具有较高优化级别的配置文件集合的典型示例:


demo% f95 -o prg -fast -xprofile=collect prg.f ...
demo% prg 
demo% f95 -o prgx -fast -O5 -xprofile=use:prg.profile prg.f ...
demo% prgx

例中的首次编译会生成一个在运行时产生语句覆盖统计的可执行文件。第二次编译使用该性能数据来指导程序的优化。

(有关 -xprofile 选项的详细信息,参见《Fortran 用户指南》。)

9.1.1.5 -dalign

使用 -dalign,只要有可能,编译器就能生成双字加载/存储指令。用该选项编译后,执行大量数据操作的程序可能会显著受益。(它是 -fast 选用的选项之一。)双字指令的速度差不多是相应的单字操作的二倍。

但是,用户应注意,对于一些程序编码期待 COMMON 块中的数据按特定方式对齐的程序,使用 -dalign 选项(因此,对于 -fast 亦是如此)可能会带来问题。使用 -dalign,编译器可能会添加补白以确保所有双精度(和四精度)数据(REAL 或 COMPLEX)在双字边界对齐,结果会造成:

例如,如果某个程序是以单个数组形式通过别名使用具有混合数据类型的整个 COMMON 块来写入数据的,则该程序在 -dalign 下可能不会正常工作,原因是块比程序预期的要大(因双精度和四精度变量的补白所致)。

9.1.1.6 -depend

-O3 及更高的优化级别添加 -depend 可扩展编译器优化 DO 循环和循环嵌套的能力。使用该选项,优化器会分析迭代间的数据依赖性,以确定是否执行某一些循环结构转换。只能重构无数据依赖性的循环。但是,增添的分析可能会增加编译时间。

9.1.1.7 -fsimple=2

除非指示这样做,否则编译器不会尝试简化浮点计算(缺省设置为 -fsimple=0)。-fsimple=2 使优化器能够进行更富有成效的简化,同时要了解,由于舍入影响,这可能会导致一些程序产生稍稍不同的结果。如果使用 -fsimple 级别 1 或级别 2,所有程序单元应以类似方式进行编译以确保数值精度的一致性。有关该选项的重要信息,参见《Fortran 用户指南 》。

9.1.1.8 -unroll=n

展开具有长迭代计数的短循环对某些例程很有利。但是,展开也会增加程序长度,甚至可能会降低其他循环的性能。如果 n=1(缺省值),优化器不会自动展开循环。如果 n 大于 1,优化器会尝试展开循环直至达到深度 n

编译器的代码产生器根据因子个数决定是否展开循环。即使该选项是以 n>1 指定的,编译器也可能拒绝展开循环。

如果可以展开具有可变循环限制的 DO 循环,已展开的版本和原始循环均会被编译。对迭代计数进行的运行时测试将决定是否适合执行已展开的循环。循环展开,特别是对于只有一条或两条语句的简单循环,会增加每次迭代执行的计算量,并且会为优化器提供调度寄存器和简化操作的更好机会。迭代次数间的权衡、循环的复杂性以及展开深度的选择都不易确定,并且可能需要进行一些试验。

下例展示如何有可能用 -unroll=4 将简单循环展开成四级深度(源代码不会随该选项而改变):

原始循环:


    DO I=1,20000
       X(I) = X(I) + Y(I)*A(I)
    END DO

经 4 次编译展开后,它会变成类似下面的样子


    DO I=1, 19997,4
       TEMP1 = X(I) + Y(I)*A(I)
       TEMP2 = X(I+1) + Y(I+1)*A(I+1)
       TEMP3 = X(I+2) + Y(I+2)*A(I+2)
       X(I+3) = X(I+3) + Y(I+3)*A(I+3)
       X(I) = TEMP1
       X(I+1) = TEMP2
       X(I+2) = TEMP3
    END DO

本例展示了一个具有固定循环计数的简单循环。对于可变循环计数,重构将更加复杂。

9.1.1.9 -xtarget=platform

如果编译器具有目标计算机硬件的精确描述,可能会提高一些程序的性能。当程序性能很重要时,目标硬件的正确说明会是非常重要的。在较新的 SPARC 处理器上运行时这一点尤其重要。但是,对于大多数程序和较早的 SPARC 处理器,性能增益是微不足道的,一般性说明可能就足够了。

Fortran 用户指南》列出了 -xtarget= 识别的所有系统名称。对于任意给定的系统名称(例如,对于 UltraSPARC-II,名称为 ultra2),-xtarget 会扩展成与该系统正确匹配的 -xarch-xcache-xchip 的组合。优化器使用这些说明来确定遵循的策略和生成的指令。

特殊设置 -xtarget=native 使优化器能够针对主机系统(执行编译的系统)编译目标代码。当编译和执行均在相同的系统上进行时,这显然是非常有益的。当执行系统未知时,针对通用体系结构进行编译较为适宜。因此,缺省设置为 -xtarget=generic,即使它有可能达不到最佳性能。

UltraSPARC-III 和 UltraSPARC-IV 支持

-xtarget-xchip 标志均接受 ultra3ultra3 变体,并且为 UltraSPARC-III 和 UltraSPARC-IV 处理器生成优化代码。当在最新的 UltraSPARC 平台上编译和运行应用程序时,请指定 -fast 标志,以便为该平台自动选择正确的编译器优化选项。

对于交叉编译(编译在非最新的 UltraSPARC 平台上进行,但生成专用于在 UltraSPARC-III 处理器上运行的二进制代码),使用下列标志:

-fast -xtarget=ultra3

使用 -m64 编译可生成 64 位代码。

有关最新 UltraSPARC 处理器的 -xtarget 标志列表,请参见《Fortran 用户指南》。

在 UltraSPARC-III 和 UltraSPARC-IV 平台上进行性能剖析(使用 -xprofile=collect:-xprofile=use:)效果尤为突出,这是因为它允许编译器识别经常执行的程序部分并进行最佳的本地化优化。

64 位 x86 平台支持

Sun Studio Fortran 编译器支持 Solaris 和 Linux x86 平台的 32 位和 64 位代码编译。

-xtarget=pentium3 标志将展开为:-xarch=sse -xchip=pentium3 -xcache=16/32/4:256/32/4.

对于 Pentium 4 系统,-xtarget=pentium4 将展开为:-xarch=sse2 -xchip=pentium4 -xcache=8/64/4:256/128/8.

新的 -m64 选项用来指定对 64 位 x64 指令集的编译。

新的 -xtarget 选项、-xtarget=opteron 为 32 位 AMD 编译指定了 -xarch-xchip-xcache 设置。

要生成 64 位代码,必须在命令行中 -fast-xtarget 的后面指定 -m64-xtarget 选项并不自动生成 64 位代码。-fast 选项也会产生 32 位代码,因为它也是一个定义 -xtarget 值的宏。所有当前 -xtarget 值(-xtarget=native64-xtarget=generic64 除外)将产生 32 位代码,因此必须在 -fast-xtarget 之后(右侧)指定 -xarch=m64 以编译 64 位代码,如下所示:

% f95 -fast -m64 % f95 -xtarget=opteron -m64

如果指定了 -xarch=amd64,编译器会立即预定义 __amd64__x86_64

在《Fortran 用户指南》中,可以找到有关 32 位和 64 位 x86 平台上的编译和性能的其他信息。

9.1.1.10 使用 -xipo 进行过程间优化

这个新的 f95 编译器标志是随 Forte Developer 6 update 2 发行版引入的,它通过调用过程间分析传递来执行整个程序优化。与 -xcrossfile 不同,-xipo 在链接步骤跨越所有目标文件进行优化,而不只限于编译命令中的源文件。

在编译和链接大型多文件应用程序时,-xipo 特别有用。用 -xipo 编译的目标文件内存有分析信息。这样便能够在源文件和预编译程序文件之上进行过程间分析。

有关如何有效使用过程间分析的详细信息,参见《Fortran 用户指南》。

9.1.1.11 添加 PRAGMA ASSUME 断言

在源代码的关键点处添加 ASSUME 指令,可以揭示用其他方法无法确定的重要程序信息,从而有助于指导编译器的优化策略。例如,可以告诉编译器 DO 循环的行程计数始终大于某个值,或某一 IF 分支很可能不会被执行。基于这些断言,编译器可以使用该信息生成更佳的代码。

作为一项附加的好处,通过启用运行时断言结果为假时的警告消息发布,程序员可以使用 ASSUME 编译指示来验证程序的执行。

有关详细信息,参见《Fortran 用户指南》第 2 章中的 ASSUME 编译指示介绍以及该手册第 3 章中的 -xassume_control 编译器命令行选项。