论文部分内容阅读
随着多媒体应用的普及,越来越多的处理器集成了SIMD扩展,并且随着SIMD扩展对浮点运算支持的完善,SIMD扩展部件被更多地应用于高性能计算领域。由于不同SIMD扩展提供的向量化指令差异较大,与底层硬件关系密切,使得难以依靠程序员手工编写向量化代码,而是更多地依靠编译器自动实现向量化功能,比如Gcc、Open64以及Icc等编译器都提供了自动向量化功能。目前主流的向量化方法有两种,传统向量化着眼于循环迭代间的并行,而SLP则对循环内基本块中的语句进行组合,这两种向量化方法各有优点和弊端,只有将两种向量化方法结合起来才能更好地进行向量化,其次对内存数据的非对齐和非连续访问以及短依赖距离循环等也给向量化带来了巨大的挑战,并且针对多重循环还缺乏有效的向量化方法;此外,针对特定SIMD扩展的特点也要对向量化算法和代码生成方法做相应的改进。本文主要以国产CPU SW1600为平台,针对SIMD平台的不同特性,提出了改进的SLP算法RLRSLP和ISGSLP;为了克服SLP只对循环内基本块中语句进行向量化的缺陷,增加了对循环整体的分析,在SLP算法中增加了一些辅助优化;根据影响多重循环向量化的主要因素,提出了一种激进的向量化方案;针对SW1600提供的向量重组指令,提出了面向SW1600的向量重组算法。本文的主要贡献和创新有以下四点:第一:由于进行了冗余load语句的删除,SLP算法在处理某些循环时的向量化效率反而不如传统向量化。为此基于SLP算法提出了保留冗余load语句的改进算法RLRSLP,为了解决保留冗余load语句带来的pack生成选择过多的问题,提出了依赖关系指导下UD扩展优先的pack生成方法,确保pack生成严格按照依赖关系进行,省去了SLP算法的调度阶段。此外,大部分的SIMD扩展都提供了较为完善高效的向量重组指令,为此,提出了ISGSLP算法,即在SLP的向量化发掘中加入一个同构语句的pack生成阶段,使其可以向量化那些存在着不连续内存访问的循环。第二:实际应用程序中非连续或者非对齐访存会阻碍程序的向量化或者造成性能损失,此外,单纯依靠SLP算法无法完美地向量化某些特殊循环,诸如规约和短依赖距离循环等,为此,本文针对SLP算法增加了一些辅助优化。针对实际应用中出现的数组引用不连续的情况,提出了一种数学模型刻画数组的访存模式和数据重组方案,以判断这些数组引用是否可以通过数组转置的方法满足连续性要求;并采用过程间数组填充,循环剥离等方法进行对齐优化。针对规约和短依赖循环等特殊情况,在SLP之前进行冗余store删除和规约变换,在SLP之后进行向量操作合并和冗余赋值语句删除等,使得能够更好地对此类循环进行向量化。第三:现有的编译器一般都只针对最内层循环进行向量化,对于多重循环缺少一种通用易行的向量化方法。为此本文提出了一种面向SLP的多重循环向量化方法,从外至内依次对各个循环层次进行分析,收集各层循环对应的一些影响向量化效果的属性值,主要包括能否对该循环进行直接循环展开和压紧,有多少数组引用相对于该循环索引连续,以及该循环所包含的区域等,然后根据这些属性值决定在哪些循环层次进行直接循环展开和压紧,最后通过ISGSLP对循环中的语句进行向量化。第四:由于向量重组指令比较复杂并且不同指令有不同的延迟,从而难以寻找一种统一高效的向量重组算法。本文针对国产CPU SW-1600提供的移位和插入提取指令进行了分析,设计了两种算法使其能以最少的移位或插入提取次数实现向量重组,并提出了一种综合这两类指令实现向量重组的高效算法。