发明名称 一种基于MIC架构处理器的向量化优化方法
摘要 本发明提供了一种基于MIC架构处理器的向量化优化方法,涉及算法数据依赖关系分析、算法向量化调整优化、向量化编译三个主要步骤,具体内容包括:算法的数据依赖分析、算法的向量化优化调整、编译器自动向量化技术、用户介入的向量化优化方法等。本发明提供的方法适用于MIC架构处理器平台的软件优化,指导软件开发人员以较短的开发周期,较低的开发成本,快速高效地对现有软件,尤其是核心算法进行向量优化改造,实现软件对向量处理器计算资源利用的最大化,最大限度地缩短软件运行时间,显著提高硬件资源利用率,提高软件的计算效率和软件整体性能。
申请公布号 CN103440229A 申请公布日期 2013.12.11
申请号 CN201310349628.8 申请日期 2013.08.12
申请人 浪潮电子信息产业股份有限公司 发明人 吴庆
分类号 G06F17/16(2006.01)I 主分类号 G06F17/16(2006.01)I
代理机构 代理人
主权项 一种基于MIC架构处理器的向量化优化方法,其特征在于,内容包括:1)对目标循环进行向量化可行性分析;2)向量化优化;3)编译器自动向量化;4)基于向量化编译指示的向量化;5)算法向量化改造;6)向量化正确性验证;通过重复以上迭代调优过程,以实现循环向量化率最大化,其中:1)对目标循环进行向量化可行性分析,是对需要向量化的循环进行数据依赖分析,排除循环迭代依赖,所谓循环迭代依赖,是指循环间存在前后依赖,导致循环不具有完全独立性,不能并行处理,从而使该循环不能被向量化;2)向量化优化,是在数据依赖关系的基础上,采用多种方法手段,使循环被向量化处理;3)编译器自动向量化,是编译器会自动分析循环间的数据依赖关系,并自主决定是否进行循环向量化;4)基于向量化编译指示的向量化,是基于数据依赖分析结果,通过在相应循环外添加编译指示语句,指导编译器对该循环进行向量化编译;5)算法向量化改造,是基于数据依赖分析结果,对算法/循环进行优化改造,包括数据结构调整、循环拆分、循环合并、循环嵌套顺序调整;6)向量化正确性验证,是验证向量化的正确性,体现在输出结果正确,误差在可以接受的范围内,具体实施步骤、方法细则如下:1)循环向量化可行性分析:编译器自动向量化过程中,可能收到某个循环无法被向量化的编译信息报告,很多时候无法向量化的原因都是循环间存在着变量依赖关系,通过阅读源代码,理解算法,必要时进行测试,确认代码中各循环结构间的数据依赖关系,进行数据依赖关系分析,是为了下一步对循环进行优化调整、并且介入编译器向量化编译行为;向量化处理的实质,就是将原本串行循环处理的计算任务,转换成若干循环同时处理的方式,因此,各次循环之间不能有前后的数据依赖关系,在实际操作中,编译器通过设置私有变量、添加原子阻塞操作,实现广义的向量化,这取决于向量化处理器硬件的设计及其所支持的指令集的设计,因此,循环可向量化的必要条件是:a)循环之间不存在依赖关系,也就是说,所有的循环能同时执行且互不干扰;b)必须是内层循环,在一个嵌套的循环中,向量器只能尝试向量化最内层的循环,查看向量器的输出信息能知道循环是否被向量化以及原因,如果影响性能的关键循环没有向量化,需要做一些算法调整,比如调整嵌套循环的顺序;另外,除了具备以上必要条件外,还要注意以下几点:(a)向量化处理的数据类型尽量一致,需要向量化处理的语句,其包含的变量尽可能做到长度一致,即数据类型尽可能一致,尽量避免在同一表达式中同时出现单精度和双精度变量;(b)向量化语句中尽可能避免函数调用:表达式中调用函数,会增加语句的复杂度,干扰编译器实施自动向量化,即使是标准的数学函数,也要尽量避免,如果一定要使用,也要尽可能使函数精度与变量精度一致;2)向量化优化,采用以下方法,实现循环的向量化处理;a)编译器自动向量化编译器自动向量化依赖于编译器自身的能力来消除内存引用二义性,Intel C/C++编译器默认向量化编译选项为‑vec,即默认情况下向量化是打开的,若关闭向量化,在编译选项中添加‑no‑vec,编译器在对源代码进行编译时,会输出编译信息/报告,某些编译器有多个编译信息输出级别,其编译信息输出级别可使用‑vec‑report  level控制,通过编译器输出的编译信息报告,以了解编译的详细细节,包括某个循环是否被向量化,向量化失败的原因,这些信息能为向量优化提供依据和指导;b)基于向量化编译指示的向量化向量化编译指示,能更好地指导编译器进行数据依赖分析,从而更好地向量化代码,包括__declspec(align(n)) 声明能够使编译器克服硬件对齐的限制,restrict修饰词和自动向量化提示解决了由于作用范围、数据依赖和二义性等产生的问题,SIMD编译指示使得最内层的循环被强制向量化,使用向量化编译指令是有风险的,使用的前提条件是程序员必须确保不存在数据依赖;其中SIMD 编译指示有五个可供选择的子句来指导编译器执行何种向量化,恰当地使用这些子句,会让编译器获得足够的信息来产生正确的向量化代码,其中:(1)vectorlength(num1, num2, …, numN)指导向量优化单元可以从指定的若干向量长度(VL)num1, num2, … , numN 中选择来向量化循环,对于选定的VL,向量循环的每一次执行的计算工作相当于原来标量循环VL 次执行的计算工作,多个向量长度子句会合并成一个集合;(2)private(expr1, expr2, …, exprN)指导向量优化单元使得这些左值(L‑value)表达式expr1, exper2, ..., exprN 对于每一次循环都是私有的,多个private 子句会合并成一个集合,左值表达式的初值将被广播到所有的私有子句,除非编译器能够判定初值未在循环体内使用;左值表达式的终值也会被从最后一次执行的循环体复制出来, 除非编译器能够判定终值未在循环后被使用;(3)linear(var1:step1, var2:step2, …, varN:stepN)指导编译器每一次标量循环的执行时,var1 的值增加step1, var2 的值增加step2, 依此类推,相应地,每次向量循环的执行,使得这些变量的值分别增加VL*step1,VL*step2, …, VL*stepN,多个linear 子句会被合并成一个集合,如果var 被赋予两个或多个step 值,会产生一个编译错误;(4)reduction(oper:var1,var2,…,varN)指导编译器对于变量var1, var2, …, varN 执行向量化规约操作oper,一个SIMD 编译指示有多个归约子句,执行相同或者不同的操作,如果一个变量var 与两个或多个不同的归约操作oper 有关, 会产生一个编译错误;(5)[no]assert指导编译器当向量化失败时是否报错,缺省是不报错的,一个SIMD 编译指令不应该存在多个该子句,否则会产生一个编译错误,为了向量化一个包含潜在依赖关系的循环,用户经过数据依赖分析后,确认其不存在循环间数据依赖,可加上#pragma ivdep提示编译器忽略存在的数据依赖关系;当向量化以上代码段中的循环时,编译器会认为该循环存在循环间依赖,即第j次循环依赖第j+k次循环的结果,这种依赖关系称为交叉迭代依赖,而如果确定k>16,超过MIC VPU的向量处理宽度,循环间就不存在实际意义上的数据依赖,加上#pragma ivdep指示编译器忽略数据的依赖关系并尝试进行向量化,甚至使用#pragma simd强制向量化该循环,如果L<k<16,那么使用#pragma simd vectorlength(L)强制向量化该循环,并且能保证结果的正确性;3)算法向量化改造如果采用以上两种向量化方式,还有部分循环无法实现向量化,在数据依赖分析的基础上,对算法进行深度优化改进,向量化改造方法有:a)调整嵌套循环的顺序;b)自动向量化只能对嵌套中的最内层的循环进行向量化,然而内层循环向量化效果未必最好,通过调整嵌套循环的顺序达到更好的向量化效果,如调整之后的向量化能实现更好的连续访问;c)拆分循环在某些情况下,除了最内层的循环比较耗时外,其它不在最内层循环的代码也比较耗时,而这部分代码是无法自动向量化的,为此,采取拆分循环的方法实现更多的自动向量化,通过对循环的拆分,能使更多的代码自动向量化,获取更好的向量化性能;d)手写SIMD指令向量化第一代Intel MIC产品为KNC(Knights Corner),Knights Corner Instructions是KNC支持的SIMD指令的总称,是类似于SSE、AVX的指令集,通过使用Knights Corner指令,能细粒度地控制向量化运算;Knights Corner Instructions分类:(1)Knights Corner指令Knights Corner instruction是指具体的SIMD指令,是汇编指令集中关于SIMD的子集;(2)内建Knights Corner(Intrinsics of Knights Corner)是对Knights Corner指令的封装,几乎涉及到所有指令,认为这些函数和数据类型是C/C++的内建类型;Knights Corner类库Knights Corner Class Libraries是为了方便使用Knights Corner指令而做的封装,让程序员尽量简单地使用SIMD指令,介于引语方式和SIMD代码之间;其支持整型和浮点型数据;4)向量化正确性验证编译源代码,然后运行程序,检查程序的输出结果,验证向量化的正确性,向量化可能会带来精度损失,必要时通过编译器的‑fp‑model选项,调整向量化的精度;5)迭代调优重复以上过程,以实现循环向量化率最大化,从而使MIC处理器VPU的计算性能尽可能发挥出来;6)性能测试及分析,包括:(1)测试环境(2)性能测试结果(3)性能测试结果分析利用该方法对矩阵乘法应用案例进行向量化改造后,显著地提升了该MIC模块的运行效率,获得了较高的性能加速比。
地址 250014 山东省济南市高新区舜雅路1036号