GCC 基础性能优化用户指南

简介

编译器基础性能优化对于提高应用程序的开发效率、运行性能和可维护性都非常重要。它是计算机科学领域的一个重要研究方向,也是软件开发过程中的重要环节之一。GCC for openEuler 在通用编译优化能力的基础上,对中后端性能优化技术进行了增强,包括指令优化、向量化增强、预取增强、数据流分析增强等优化。

安装与部署

软件要求

操作系统:openEuler 22.03 LTS SP4

硬件要求

aarch64 架构

安装软件

按需安装 GCC 和相关组件即可,以 GCC 为例。

shell
yum install gcc

使用方法

CRC优化

说明

识别CRC软件循环代码,生成高效硬件指令。

使用方法

在编译时增加 -floop-crc 选项。

注:-floop-crc选项需要和-O3 -march=armv8.1-a一起使用。

If-conversion 增强

说明

增强 If conversion 优化,使用更多的寄存器以减少冲突。

使用方法

本优化是 RTL 优化 if-conversion 的一部分,使用如下编译选项控制优化启用。

-fifcvt-allow-complicated-cmps

-param=ifcvt-allow-register-renaming=[0,1,2]默认为0,数字用于控制优化范围。

注:此优化依赖-O2优化等级,以及与--param=max-rtl-if-conversion-unpredictable-cost=48--param=max-rtl-if-conversion-predictable-cost=48共同使用。

乘法计算优化

说明

Arm 相关指令合并优化,实现32位复杂组合的64位整形乘法逻辑的识别,并以高效的64位指令数输出。

使用方法

使用-fuaddsub-overflow-match-all-fif-conversion-gimple选项使能优化。

注:此优化需要-O3及以上优化等级以及-ftree-fold-phiopt选项共同使用。

cmlt 指令生成优化

说明

对一些四则运算生成cmlt指令,减少指令数。

使用方法

使用选项-mcmlt-arith使能优化。

注:此优化需要-O3以上优化等级使用。

向量化优化增强

说明

识别并简化向量化过程中生成的冗余指令,允许更短的循环进入向量化。

使用方法

使用参数--param=tree-forwprop-perm=1--param=vect-alias-flexible-segment-len=1使能,默认均为0。

注:此优化需要-O3及以上优化等级。

min max 和 uzp1/uzp2 指令联合优化

说明

识别 min max 和 uzp1/uzp2 指令联合优化机会,减少指令数从而提升性能。

使用方法

使用-fconvert-minmax选项使能min max优化,uzp1/uzp2指令优化在-O3以上等级默认使能。

注:依赖-O3及以上优化等级。

ldp/stp 优化

说明

识别某些性能表现差的 ldp/stp,将其拆分成2个 ldr 和 str。

使用方法

使用-fsplit-ldp-stp选项使能优化,使用参数--param=param-ldp-dependency-search-range=[1,32]控制搜索范围,默认16。

注:依赖-O1及以上优化等级。

AES指令优化

说明

识别 AES 软件算法指令序列,使用硬件指令加速。

使用方法

使用-fcrypto-accel-aes选项使能优化。

注:依赖-O3及以上优化等级。

间接调用提升

说明

识别和分析程序中的间接调用,尝试将其优化为直接调用。

使用方法

使用选项-ficp -ficp-speculatively使能优化。

注:此优化需要和-O2 -flto -flto-partition=one共同使用。

IPA-prefetch

说明

识别循环中的间接访存,插入预取指令,从而减少间接访存的延迟。

使用方法

通过选项-fipa-prefetch -fipa-ic使能优化。

注:此优化需要和-O3 -flto共同使用。

LLC-prefetch

说明

通过分析程序中主要的执行路径,对主路径上的循环进行访存的复用分析,计算排序出 TOP 的热数据,并插入预取指令将数据先分配至 LLC 中,减少 LLC miss。

使用方法

使能 LLC 特性,需开启 -O2 及以上优化等级,同时使用编译选项 -fllc-allocate。

其他相关接口:

选项默认值说明
-param=mem-access-ratio=[0,100]20循环内访存数对指令数的占比。
-param=mem-access-num=unsigned3循环内访存数量。
-param=outer-loop-nums=[1,10]1允许扩展的外层循环的最大层数。
-param=filter-kernels=[0,1]1是否针对循环做路径串联筛选。
-param=branch-prob-threshold=[50,100]80高概率执行分支的概率阈值。
-param=prefetch-offset=[1,999999]1024预取偏移距离,一般为2的次幂。
-param=issue-topn=unsigned1预取指令个数。
-param=force-issue=[0,1]0是否执行强制预取,即静态模式。
-param=llc-capacity-per-core=[0,999999]114多分支预取下每个核平均分配的 LLC 容量。