CN103440229B - 一种基于mic架构处理器的向量化优化方法 - Google Patents
一种基于mic架构处理器的向量化优化方法 Download PDFInfo
- Publication number
- CN103440229B CN103440229B CN201310349628.8A CN201310349628A CN103440229B CN 103440229 B CN103440229 B CN 103440229B CN 201310349628 A CN201310349628 A CN 201310349628A CN 103440229 B CN103440229 B CN 103440229B
- Authority
- CN
- China
- Prior art keywords
- vectorization
- circulation
- compiler
- vector
- simd
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
- 238000000034 method Methods 0.000 title claims abstract description 47
- 238000005457 optimization Methods 0.000 title claims abstract description 22
- 239000013598 vector Substances 0.000 claims abstract description 66
- 238000004422 calculation algorithm Methods 0.000 claims abstract description 29
- 238000004458 analytical method Methods 0.000 claims abstract description 27
- 230000009466 transformation Effects 0.000 claims abstract description 12
- 230000004087 circulation Effects 0.000 claims description 118
- 238000012545 processing Methods 0.000 claims description 28
- 230000006870 function Effects 0.000 claims description 14
- 238000012795 verification Methods 0.000 claims description 13
- 125000004122 cyclic group Chemical group 0.000 claims description 11
- 230000009467 reduction Effects 0.000 claims description 10
- 238000011056 performance test Methods 0.000 claims description 9
- 230000008859 change Effects 0.000 claims description 7
- 230000000694 effects Effects 0.000 claims description 7
- 238000013461 design Methods 0.000 claims description 6
- 238000005538 encapsulation Methods 0.000 claims description 6
- 238000011156 evaluation Methods 0.000 claims description 6
- 239000011159 matrix material Substances 0.000 claims description 6
- 101100129590 Schizosaccharomyces pombe (strain 972 / ATCC 24843) mcp5 gene Proteins 0.000 claims description 5
- 238000005194 fractionation Methods 0.000 claims description 5
- 238000012360 testing method Methods 0.000 claims description 5
- 230000001419 dependent effect Effects 0.000 claims description 4
- 230000009471 action Effects 0.000 claims description 3
- 230000006399 behavior Effects 0.000 claims description 3
- 230000000903 blocking effect Effects 0.000 claims description 3
- 230000001351 cycling effect Effects 0.000 claims description 3
- 230000006872 improvement Effects 0.000 claims description 3
- 238000007620 mathematical function Methods 0.000 claims description 3
- 230000008569 process Effects 0.000 claims description 3
- 238000007634 remodeling Methods 0.000 claims description 3
- 230000010429 evolutionary process Effects 0.000 claims description 2
- 230000004927 fusion Effects 0.000 claims description 2
- 101100517651 Caenorhabditis elegans num-1 gene Proteins 0.000 claims 1
- 238000005516 engineering process Methods 0.000 abstract description 4
- 238000010276 construction Methods 0.000 abstract description 3
- 238000011161 development Methods 0.000 abstract description 3
- 238000010586 diagram Methods 0.000 description 3
- 239000012141 concentrate Substances 0.000 description 2
- 235000013399 edible fruits Nutrition 0.000 description 2
- 238000007667 floating Methods 0.000 description 2
- 238000013459 approach Methods 0.000 description 1
- 238000003491 array Methods 0.000 description 1
- 230000009286 beneficial effect Effects 0.000 description 1
- 239000012634 fragment Substances 0.000 description 1
- 238000013139 quantization Methods 0.000 description 1
Landscapes
- Devices For Executing Special Programs (AREA)
Abstract
本发明提供了一种基于MIC架构处理器的向量化优化方法,涉及算法数据依赖关系分析、算法向量化调整优化、向量化编译三个主要步骤,具体内容包括:算法的数据依赖分析、算法的向量化优化调整、编译器自动向量化技术、用户介入的向量化优化方法等。本发明提供的方法适用于MIC架构处理器平台的软件优化,指导软件开发人员以较短的开发周期,较低的开发成本,快速高效地对现有软件,尤其是核心算法进行向量优化改造,实现软件对向量处理器计算资源利用的最大化,最大限度地缩短软件运行时间,显著提高硬件资源利用率,提高软件的计算效率和软件整体性能。
Description
技术领域
本发明涉及计算机高性能计算领域、科学计算领域,具体涉及一种基于MIC架构处理器的向量化优化方法。
背景技术
自从1996年Intel在奔腾处理器上集成了MMX后,越来越多的通用处理器上集成了SIMD(Single Instruction Multiple Data,单指令多数据流)硬件扩展,这种集成了SIMD处理架构的处理器,称为向量处理器。向量处理器的应用也越来越广泛,从最初的多媒体应用扩展到各个应用领域,尤其在高性能计算领域,海量数据、大规模并行处理需求,对处理器的计算能力提出严峻挑战,向量化的并行处理,能有效提高并行处理效率和计算密度,提高硬件资源利用率,进而降低计算成本。
新的MIC架构协处理器具备当前最宽的向量宽度,它构建在至强处理器的并行架构之上,通过集成众多低功耗内核,每一个处理器核具备一个512位的SIMD处理单元和很多新的向量运算指令,MIC架构处理器创造了在一个芯片上的超级计算机,超过每秒一万亿次的计算能力。
随着MIC架构处理器的推广,其强大的SIMD扩展技术将被广泛应用,不仅为高性能计算提供了新的解决问题、提升性能的途径,也带来了一个新的问题——如何快速、高效地实现可靠的向量化并行处理,从而充分释放MIC处理器的计算潜力?这是摆在软件工程师面前的现实挑战。
发明内容
本发明的目的是提供一种基于MIC架构处理器的向量化优化方法。
本发明的目的是按以下方式实现的,内容包括:1)对目标循环进行向量化可行性分析;2)向量化优化;3)编译器自动向量化;4)基于向量化编译指示的向量化;5)算法向量化改造;6)向量化正确性验证;通过重复以上迭代调优过程,以实现循环向量化率最大化,其中:
[1]对目标循环进行向量化可行性分析,是对需要向量化的循环进行数据依赖分析,排除循环迭代依赖,所谓循环迭代依赖,是指循环间存在前后依赖,导致循环不具有完全独立性,不能并行处理,从而使该循环不能被向量化;
[2]向量化优化,是在数据依赖关系的基础上,采用多种方法手段,使循环被向量化处理;
[3]编译器自动向量化,是编译器会自动分析循环间的数据依赖关系,并自主决定是否进行循环向量化;
[4]基于向量化编译指示的向量化,是基于数据依赖分析结果,通过在相应循环外添加编译指示语句,指导编译器对该循环进行向量化编译;
[5]算法向量化改造,是基于数据依赖分析结果,对算法/循环进行优化改造,包括数据结构调整、循环拆分、循环合并、循环嵌套顺序调整;
[6]向量化正确性验证,是验证向量化的正确性,体现在输出结果正确,误差在可以接受的范围内;
具体实施步骤、方法细则如下:
2)[1]循环向量化可行性分析。
编译器自动向量化过程中,可能收到某个循环无法被向量化的编译信息,很多时候无法向量化的原因都是循环间存在着变量依赖关系,通过阅读源代码,理解算法,必要时进行测试,确认代码中各循环结构间的数据依赖关系,进行数据依赖关系分析,是为了下一步对循环进行优化调整、并且介入编译器向量化编译行为;
向量化处理的实质,就是将原本串行循环处理的计算任务,转换成若干循环同时处理的方式,因此,各次循环之间不能有前后的数据依赖关系,在实际操作中,编译器通过设置私有变量、添加原子阻塞操作,实现广义的向量化,这取决于向量化处理器硬件的设计及其所支持的指令集的设计,因此,循环可向量化的必要条件是:
a)循环之间不存在依赖关系,也就是说,所有的循环能同时执行且互不干扰;
b)必须是内层循环,在一个嵌套的循环中,向量器只能尝试向量化最内层的循环,查看向量器的输出信息能知道循环是否被向量化以及原因,如果影响性能的关键循环没有向量化,需要做一些算法调整,比如调整嵌套循环的顺序;
另外,除了具备以上必要条件外,还要注意以下几点:
(a)向量化处理的数据类型尽量一致,需要向量化处理的语句,其包含的变量数据类型一致,尽量避免在同一表达式中同时出现单精度和双精度变量;
(b)向量化语句中尽可能避免函数调用:表达式中调用函数,会增加语句的复杂度,干扰编译器实施自动向量化,即使是标准的数学函数,也要尽量避免,如果一定要使用,也要尽可能使函数精度与变量精度一致;
[2]向量化优化,采用以下方法,实现循环的向量化处理;
[3]编译器自动向量化
编译器自动向量化依赖于编译器自身的能力来消除内存引用二义性,编译器默认向量化编译选项为-vec,即默认情况下向量化是打开的,若关闭向量化,在编译选项中添加-no-vec,编译器在对源代码进行编译时,会输出编译信息,某些编译器有多个编译信息输出级别,其编译信息输出级别可使用-vec-report level控制,通过编译器输出的编译信息,以了解编译的详细细节,包括某个循环是否被向量化,向量化失败的原因,这些信息能为向量优化提供依据和指导;
[4]基于向量化编译指示的向量化
向量化编译指示,能指导编译器进行数据依赖分析,从而向量化代码,包括
__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,超过MICVPU的向量处理宽度,循环间就不存在实际意义上的数据依赖,加上#pragma ivdep指示编译器忽略数据的依赖关系并尝试进行向量化,甚至使用#pragma simd强制向量化该循环,如果L<k<16,那么使用#pragma simd vectorlength(L)强制向量化该循环,并且能保证结果的正确性;
[5]算法向量化改造
如果采用以上两种向量化方式,还有部分循环无法实现向量化,在数据依赖分析的基础上,对算法进行深度优化改进,向量化改造方法有:
a)调整嵌套循环的顺序
b)自动向量化只能对嵌套中的最内层的循环进行向量化,然而内层循环向量化效果未必最好,通过调整嵌套循环的顺序达到更好的向量化效果,调整之后的向量化能实现更好的连续访问;
c)拆分循环
在某些情况下,除了最内层的循环比较耗时外,其它不在最内层循环的代码也比较耗时,而这部分代码是无法自动向量化的,为此,采取拆分循环的方法实现更多的自动向量化,通过对循环的拆分,能使更多的代码自动向量化,获取更好的向量化性能;
d)手写SIMD指令向量化
第一代Intel MIC产品为Knights Corner,Knights Corner Instructions是Knights Corner支持的SIMD指令的总称,是类似于SSE、AVX的指令集,通过使用KnightsCorner指令,能细粒度地控制向量化运算;
Knights Corner Instructions分类:
(1)Knights Corner指令Knights Corner instruction是指具体的SIMD指令,是汇编指令集中关于SIMD的子集;
(2)Intrinsics of Knights Corner是对Knights Corner指令的封装,几乎涉及到所有指令,认为这些函数和数据类型是C/C++的内建类型;
Knights Corner类库Knights Corner Class Libraries是为了方便使用KnightsCorner指令而做的封装,让程序员尽量简单地使用SIMD指令,介于引语方式和SIMD代码之间;其支持整型和浮点型数据;
[6]向量化正确性验证
编译源代码,然后运行程序,检查程序的输出结果,验证向量化的正确性,向量化可能会带来精度损失,必要时通过编译器的-fp-model选项,调整向量化的精度;
(a)迭代调优
重复以上过程,以实现循环向量化率最大化,从而使MIC处理器VPU的计算性能尽可能发挥出来;
(b)性能测试及分析,包括:
(1)测试环境
平台 | Inspur NF5280M3 |
CPU | Intel Xeon CPU E5675 3.07GHz,双路8核 |
Memory | DDR3 1333MHz 128GB |
MIC | KNC,60核,1.0GHz,GDDR5 8GB memory5.5GT/s |
OS | Red Hat Enterprise Linux Server release 6.1,64bit |
编译器 | icc |
测试用例 | 4096*4096矩阵乘法 |
(2)性能测试结果
程序版本 | 版本说明 | 时间(s) |
P_baseline | CPU单线程基准版 | 312.83 |
P_OMP | CPU多线程+自动向量化版 | 170.83 |
P_MIC_base | MIC多线程+自动向量化版 | 174 |
P_baseline_vec | CPU单线程+算法向量化改造+向量化指示版 | 25 |
P_OMP_vec | CPU多线程+算法向量化改造+向量化指示版 | 4.53 |
P_MIC_vec | MIC多线程+算法向量化改造+向量化指示版 | 3.43 |
P_MIC_simd | MIC多线程+算法向量化改造+向量化指示+simd指令版 | 2 |
(3)性能测试结果分析
利用该方法对矩阵乘法应用案例进行向量化改造后,显著地提升了该模块的运行效率,获得了较高的性能加速比。
编译过程中所使用的编译器,是支持MIC架构及其指令集的任意编译器,该编译器生成的目标代码,直接或通过后续编译处理后,能够运行于MIC架构处理器。
本发明的有益效果是:该方法广泛适用于MIC架构处理器并行处理的应用场合,指导软件开发人员以较短的开发周期,较低的开发成本,快速高效地对现有软件进行向量化优化改造,实现软件对系统资源利用最优化,显著提高硬件资源利用率和软件的计算效率,从而大大提升软件整体性能。
附图说明
图1是单精度浮点数据向量化处理示意图。
图2是向量化的层次示意图。
具体实施方式
参照说明书附图对本发明的方法作以下详细地说明。
本发明提供了一种基于MIC架构处理器的向量化优化方法。其主要内容是提供一种利用MIC架构协处理器计算设备,最大化提高MIC硬件资源利用率,从而提升MIC处理器平台上软件运行效能的方法。该方法提出,基于MIC架构处理器的向量化优化流程如下:
1)对目标循环进行向量化可行性分析。
2)向量化优化
3)编译器自动向量化
4)基于向量化编译指示的向量化
5)算法向量化改造
6)向量化正确性验证。
重复以上过程,迭代调优,以实现循环向量化率最大化。
实施例
首先,简要介绍向量化处理原理及MIC处理器的向量处理单元VPU(VectorProcess Unit)的架构。MIC处理器核的VPU支持512bit位宽的KCi向量指令,支持16*32bit或8*64bit等多种处理模式,即向量化宽度为8或16。512位相当于16个单精度浮点型数据的长度,单精度浮点数据向量化处理示意图如图1所示:
例如向量加操作C[0~15]=A[0~15]+B[0~15](A、B、C均为float型数据),没有使用向量化时这个操作需要16次加运算,而向量化之后,把A、B、C放到向量寄存器中,进行一次向量加操作即可完成原来的16次加操作,因此,向量化可以大大提高计算速度。
以下说明都基于intel的编译器和C语言进行阐述。
一种基于MIC架构处理器的向量化优化实施步骤、方法细则如下:
[1]对目标循环进行向量化可行性分析
编译器自动向量化过程中,可能收到某个循环无法被向量化的编译信息。很多时候无法向
量化的原因都是循环间存在着变量依赖关系。
通过阅读源代码,理解算法,必要时进行测试,确认代码中各循环结构间的数据依赖关系。进行数据依赖关系分析,是为了下一步对循环进行优化调整、并且介入编译器向量化编译行为。
向量化处理的实质,就是将原本串行循环处理的计算任务,转换成若干循环同时处理的方式,因此,原理上,各次循环之间不能有前后的数据依赖关系。当然,在实际操作中,编译器可以通过设置私有变量、添加原子阻塞操作等方式,实现广义的向量化,这取决于向量化处理器硬件的设计及其所支持的指令集的设计。
因此,循环可向量化的必要条件是:
c)循环之间不存在依赖关系。
也就是说,所有的循环能同时执行且互不干扰。例如:
for(int i=0;i<1000;i++)
{
s1:a[i]=b[i]*T+d[i];
s2:b[i]=(a[i]+b[i])/2;
s3:c=c+b[i];
}
等价于下面的操作:
for(int i=0;i<1000;i++)a[i]=b[i]*T+d[i];
for(int i=0;i<1000;i++)b[i]=(a[i]+b[i])/2;
for(int i=0;i<1000;i++)c=c+b[i];
因此,这个循环是可以被向量化的。
再看一个例子:
for(int i=1;i<1000;i++)
{
s1:a[i]=a[i-1]*b[i];
}
无论如何,这个循环是不能被向量化的,因为a[i]在每次迭代中都依赖前一次迭代的结果。我们称这是一个交叉迭代的数据依赖或者“flow dependence”,这样的循环不能被编译器向量化。
d)必须是内层循环。
在一个嵌套的循环中,向量器只能尝试向量化最内层的循环,查看向量器的输出信息可以知道循环是否被向量化以及原因,如果影响性能的关键循环没有向量化,你可能需要做一些算法调整,比如调整嵌套循环的顺序。
另外,除了具备以上必要条件外,还要注意以下几点:
(1)向量化处理的数据类型尽量一致
需要向量化处理的语句,其包含的变量数据类型一致。如,尽量避免在同一表达式中同时出现单精度和双精度变量。
(2)向量化语句中尽可能避免函数调用:表达式中调用函数,会增加语句的复杂度,干扰编译器实施自动向量化,即使是标准的数学函数,也要尽量避免,如果一定要使用,也要尽可能使函数精度与变量精度一致,如:
[2]向量化优化
采用以下多种方法,实现循环的向量化处理。
[3]编译器自动向量化
编译器自动向量化依赖于编译器自身的能力来消除内存引用二义性。编译器,默认向量化编译选项为-vec,即默认情况下向量化是打开的,若关闭向量化可以在编译选项中添加-no-vec。编译器在对源代码进行编译时,会输出编译信息,某些编译器有多个编译信息输出级别,其编译信息输出级别使用-vec-report level控制,见下表:
-vec-report[level] | 含义 |
0 | 不显示诊断信息。 |
1 | 只显示已向量化的循环(默认值)。 |
2 | 显示已向量化和未向量化的循环。 |
3 | 显示已向量化和未向量化的循环以及数据依赖信息。 |
4 | 只显示未向量化的循环。 |
5 | 显示未向量化的循环以及数据依赖信息。 |
通过编译器输出的编译信息,可以了解编译的详细细节,比如某个循环是否被向量化,向量化失败的原因等,这些信息可以为向量优化提供依据和指导。
[4]基于向量化编译指示的向量化
向量化编译指示,可以指导编译器进行数据依赖分析,从而向量化代码。
例如__declspec(align(n))声明能够使编译器克服硬件对齐的限制。restrict修饰词和自动向量化提示解决了由于作用范围、数据依赖和二义性等产生的问题。SIMD编译指示使得最内层的循环被强制向量化。使用向量化编译指令是有风险的,使用的前提条件是程序员必须确保不存在数据依赖。
Intel编译器向量化编译指示如下表:
其中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)强制向量化该循环,并且能保证结果的正确性。
[5]算法向量化改造
如果采用以上两种向量化方式,还有部分循环无法实现向量化,可以在数据依赖分析的基础上,对算法进行深度优化改进。主要的向量化改造方法有:
a)调整嵌套循环的顺序
自动向量化只能对嵌套中的最内层的循环进行向量化,然而内层循环向量化效果未必最好,我们可以通过调整嵌套循环的顺序达到更好的向量化效果,如调整之后的向量化可以实现更好的连续访问,如下面的代码所示,B代码的向量化效果比A的好。
b)拆分循环
在某些情况下,除了最内层的循环比较耗时外,其它不在最内层循环的代码也比较耗时,而这部分代码是无法自动向量化的,为此,我们可以采取拆分循环的方法实现更多的自动向量化,下面通过一段伪代码说明其使用方法。
假设上面的代码中循环无数据依赖,由于rand函数无法向量化,从而导致整个循环无法向量化,我们可以把一个循环拆成两个循环的方法达到第二个for循环(主要耗时的)实现向量化的目的,代码如下:
另一个例子:
假设上面的代码中两层循环均无数据依赖,除了内层循环for(j=0;j<M;j++)比较耗时,对于s的求解也很耗时,然而求解s的部分是无法自动向量化的。我们可以通过拆分外层的循环做到自动向量化效果,修改后的伪代码如下:
}通过对循环的拆分,我们可以使更多的代码自动向量化,可以获取更好的向量化性能。
C)手写SIMD指令向量化
向量化的层次如图2所示,越往上的级别,使用的语言越低级,编程越复杂,但控制的灵活性越好,理论上性能也越高。相反的,越往下的级别,编程越容易,但性能可能不是最理想。
第一代Intel MIC产品为Knights Corner,Knights Corner Instructions是KNC支持的SIMD指令的总称。可以看作是类似于SSE、AVX等的指令集。通过使用Knights Corner指令,可以细粒度地控制向量化运算。
Knights Corner Instructions分类:
(1)Knights Corner指令Knights Corner instruction是指具体的SIMD指令,是汇编指令集中关于SIMD的子集。
(2)Intrinsics of Knights Corner是对Knights Corner指令的封装(几乎涉及到所有指令),可以认为这些函数和数据类型是C/C++的内建类型。
(3)Knights Corner类库(Knights Corner Class Libraries)是为了方便使用Knights Corner指令而做的封装,可以让程序员尽量简单地使用SIMD指令,介于引语方式和SIMD代码之间。其支持整型和浮点型数据。
下面通过单精度浮点向量加的例子说明三者的区别:
通过上面的例子可以看出使用类库的方式非常简单,能够以最类似于标量的方式(把数组看成变量),进行向量化改造。而直接使用Knights Corner则更接近常规的思维方式,将两个数组通过向量化函数进行运算,当然,其代码要比使用类库方式复杂一些,但由于减少了封装和调用,因此性能也会略有提高。而内联汇编则是最难阅读的,由于最贴近底层,因而执行效率也最高,只是编程的成本也是最高的。在实际的SIMD指令编写中,我们一般采用Knights Corner的方式。
下面我们通过一个向量加的示例说明SIMD指令的使用方法。
SIMD指令与汇编指令类似,可读性较差,并且严重依赖于硬件,可移植性差。因此,SIMD指令一般选择性使用,如代码量较少,计算却十分密集的地方。
[6]向量化正确性验证。
编译源代码,然后运行程序,检查程序的输出结果,验证向量化的正确性。
向量化可能会带来精度损失,必要时可以通过编译器的-fp-model选项,调整向量化的精度。
重复以上过程,以实现循环向量化率最大化,从而使MIC处理器VPU的计算性能尽可能发挥出来。
3、性能测试及分析
将该方法应用于一个典型的高性能运算案例——矩阵乘法。
1)测试环境
平台 | Inspur NF5280M3 |
CPU | Intel Xeon CPU E5675 3.07GHz,双路8核 |
Memory | DDR3 1333MHz 128GB |
MIC | KNC,60核,1.0GHz,GDDR5 8GB memory5.5GT/s |
OS | Red Hat Enterprise Linux Server release 6.1,64bit |
编译器 | icc |
测试用例 | 4096*4096矩阵乘法 |
2)性能测试结果
3)性能测试结果分析
利用该方法对矩阵乘法应用案例进行向量化改造后,显著地提升了该模块的运行效率,获得了较高的性能加速比。
4、总结
由本发明的技术方案可见,本发明提供了一种基于MIC架构处理器的向量化优化方法,该方法广泛适用于MIC架构处理器并行处理的应用场合,指导软件开发人员以较短的开发周期,较低的开发成本,快速高效地对现有软件进行向量化优化改造,实现软件对系统资源利用最优化,显著提高硬件资源利用率和软件的计算效率,从而大大提升软件整体性能。
除说明书所述的技术特征外,均为本专业技术人员的已知技术。
Claims (2)
1.一种基于MIC架构处理器的向量化优化方法,其特征在于,内容包括:1)对目标循环进行向量化可行性分析;2)向量化优化;3)编译器自动向量化;4)基于向量化编译指示的向量化;5)算法向量化改造;6)向量化正确性验证;通过重复迭代调优过程,以实现循环向量化率最大化,其中:
1)对目标循环进行向量化可行性分析,是对需要向量化的循环进行数据依赖分析,排除循环迭代依赖,所谓循环迭代依赖,是指循环间存在前后依赖,导致循环不具有完全独立性,不能并行处理,从而使循环不能被向量化;
2)向量化优化,是在数据依赖关系的基础上,采用多种方法手段,使循环被向量化处理;
3)编译器自动向量化,是编译器会自动分析循环间的数据依赖关系,并自主决定是否进行循环向量化;
4)基于向量化编译指示的向量化,是基于数据依赖分析结果,通过在相应循环外添加编译指示语句,指导编译器对循环进行向量化编译;
5)算法向量化改造,是基于数据依赖分析结果,对算法/循环进行优化改造,包括数据结构调整、循环拆分、循环合并、循环嵌套顺序调整;
6)向量化正确性验证,是验证向量化的正确性,体现在输出结果正确,误差在可以接受的范围内;
具体实施步骤、方法细则如下:
[1]循环向量化可行性分析
编译器自动向量化过程中,会收到某个循环无法被向量化的编译信息,很多时候无法向量化的原因都是循环间存在着变量依赖关系,通过阅读源代码,理解算法,进行测试,确认代码中各循环结构间的数据依赖关系,进行数据依赖关系分析,是为了下一步对循环进行优化调整、并且介入编译器向量化编译行为;
向量化处理的实质,就是将原本串行循环处理的计算任务,转换成若干循环同时处理的方式,因此,各次循环之间不能有前后的数据依赖关系,在实际操作中,编译器通过设置私有变量、添加原子阻塞操作,实现广义的向量化,这取决于向量化处理器硬件的设计及其所支持的指令集的设计,因此,循环可向量化的必要条件是:
a)循环之间不存在依赖关系,也就是说,所有的循环能同时执行且互不干扰;
b)必须是内层循环,在一个嵌套的循环中,向量器只能尝试向量化最内层的循环,查看向量器的输出信息能知道循环是否被向量化及无法向量化的原因,如果影响性能的关键循环没有向量化,需要做算法调整,调整嵌套循环的顺序;
另外,除了具备以上必要条件外,还要注意以下几点:
(a)向量化处理的数据类型要一致,需要向量化处理的语句,其包含的变量要做到数据类型要一致,要避免在同一表达式中同时出现单精度和双精度变量;
(b)向量化语句中要避免函数调用:表达式中调用函数,会增加语句的复杂度,干扰编译器实施自动向量化,即使是标准的数学函数,也要避免,如果一定要使用,也要使函数精度与变量精度一致;
[2]向量化优化,采用以下方法,实现循环的向量化处理:
a)编译器自动向量化
编译器自动向量化依赖于编译器自身的能力来消除内存引用二义性,编译器默认向量化编译选项为-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,即k超过MICVPU的向量处理宽度,循环间就不存在实际意义上的数据依赖,加上#pragma ivdep指示编译器忽略数据的依赖关系并尝试进行向量化,甚至使用#pragma simd强制向量化该循环,如果L<k<16,那么使用#pragma simd vectorlength(L)强制向量化该循环,并且能保证结果的正确性;
[3]算法向量化改造
如果采用循环向量化和编译器自动向量化两种向量化方式,还有部分循环无法实现向量化,在数据依赖分析的基础上要对算法进行深度优化改进,向量化改造方法有:
a)调整嵌套循环的顺序;
b)自动向量化只能对嵌套中的最内层的循环进行向量化,然而内层循环向量化效果不是最好,通过调整嵌套循环的顺序达到更好的向量化效果,调整之后的向量化能实现更好的连续访问;
c)拆分循环
除了最内层的循环比较耗时外,其它不在最内层循环的代码也比较耗时,而这部分代码是无法自动向量化的,为此,采取拆分循环的方法实现更多的自动向量化,通过对循环的拆分,能使更多的代码自动向量化,获取更好的向量化性能;
d)手写SIMD指令向量化
第一代Intel MIC产品为Knights Corner,Knights Corner Instructions是KnightsCorner支持的SIMD指令的总称,
是类似于SSE、AVX的指令集,通过使用Knights Corner指令,能细粒度地控制向量化运算;
Knights Corner Instructions分类:
(1)Knights Corner指令Knights Corner instruction是指具体的SIMD指令,是汇编指令集中关于SIMD的子集;
(2)Intrinsics of Knights Corner是对Knights Corner指令的封装,涉及到的所有指令,认为这些函数和数据类型是C/C++的内建类型;
Knights Corner类库Knights Corner Class Libraries是为了方便使用KnightsCorner指令而做的封装,让程序员尽量简单地使用SIMD指令,介于引语方式和SIMD代码之间;其支持整型和浮点型数据;
[4]向量化正确性验证
编译源代码,然后运行程序,检查程序的输出结果,验证向量化的正确性,向量化可能会带来精度损失,能够通过编译器的-fp-model选项,调整向量化的精度;
[5]迭代调优
重复以上过程,以实现循环向量化率最大化,从而使MIC架构处理器VPU的计算性能发挥出来;
[6]性能测试及分析,包括:
(a)测试环境
(b)性能测试结果
(c)性能测试结果分析
通过对矩阵乘法应用案例进行向量化改造后,显著地提升了该MIC架构处理器的运行效率,获得了较高的性能加速比。
2.根据权利要求1所述的方法,其特征在于,编译过程中所使用的编译器,是支持MIC架构及其指令集的任意编译器,该编译器生成的目标代码,直接运行于MIC架构处理器或通过后续编译处理后再运行于MIC架构处理器。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201310349628.8A CN103440229B (zh) | 2013-08-12 | 2013-08-12 | 一种基于mic架构处理器的向量化优化方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201310349628.8A CN103440229B (zh) | 2013-08-12 | 2013-08-12 | 一种基于mic架构处理器的向量化优化方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN103440229A CN103440229A (zh) | 2013-12-11 |
CN103440229B true CN103440229B (zh) | 2017-11-10 |
Family
ID=49693921
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201310349628.8A Active CN103440229B (zh) | 2013-08-12 | 2013-08-12 | 一种基于mic架构处理器的向量化优化方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN103440229B (zh) |
Families Citing this family (20)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US9471289B2 (en) * | 2014-03-25 | 2016-10-18 | Nec Corporation | Compiler optimization for many integrated core processors |
CN104112264A (zh) * | 2014-07-15 | 2014-10-22 | 东南大学 | 一种基于局部方差图像增强的优化方法 |
CN104346318B (zh) * | 2014-10-15 | 2017-03-15 | 中国人民解放军国防科学技术大学 | 面向通用多核dsp的矩阵乘加速方法 |
CN104360985A (zh) * | 2014-10-20 | 2015-02-18 | 浪潮电子信息产业股份有限公司 | 一种基于mic实现聚类算法的方法及装置 |
CN105242907B (zh) * | 2015-09-10 | 2018-01-19 | 西安交通大学 | Arm二进制代码的neon向量化转换方法 |
CN105204822A (zh) * | 2015-10-27 | 2015-12-30 | 浪潮(北京)电子信息产业有限公司 | 一种基于mic协处理器的多数据流处理方法 |
CN105808310A (zh) * | 2016-04-01 | 2016-07-27 | 浪潮电子信息产业股份有限公司 | 一种适用于大规模并行软件GTC的核心模块Pushe的高效向量化方法 |
CN106959937B (zh) * | 2017-03-30 | 2019-03-29 | 中国人民解放军国防科学技术大学 | 一种面向gpdsp的反卷积矩阵的向量化实现方法 |
CN107193535B (zh) * | 2017-05-16 | 2019-11-08 | 中国人民解放军信息工程大学 | 基于simd扩展部件的嵌套循环向量并行的实现方法及其装置 |
CN108416056B (zh) * | 2018-03-21 | 2020-12-04 | 哈工大大数据(哈尔滨)智能科技有限公司 | 基于条件包含依赖的相关性学习方法、装置、设备及介质 |
CN111428327A (zh) * | 2018-12-24 | 2020-07-17 | 深圳市中兴微电子技术有限公司 | 一种指令硬件架构的构建方法、装置及存储介质 |
CN110673877B (zh) * | 2019-08-22 | 2020-09-01 | 成都信息工程大学 | 一种基于手动向量化的并行计算方法 |
CN110795106B (zh) * | 2019-10-30 | 2022-10-04 | 中国人民解放军战略支援部队信息工程大学 | 程序向量化过程中动静结合的内存别名分析处理方法及装置 |
CN113704687B (zh) * | 2020-05-21 | 2024-04-05 | 杭州海康威视数字技术股份有限公司 | 一种张量计算运行方法、装置及运算系统 |
US11714619B2 (en) | 2020-12-17 | 2023-08-01 | Huawei Technologies Co., Ltd. | Method and apparatus for retaining optimal width vector operations in arbitrary/flexible vector width architecture |
CN112947932A (zh) * | 2021-02-24 | 2021-06-11 | 上海商汤智能科技有限公司 | 对编译过程中的向量化进行优化的方法、装置及电子设备 |
CN114637388A (zh) * | 2022-03-18 | 2022-06-17 | 中国科学院计算技术研究所 | 面向数据流处理器的功耗控制方法及装置 |
CN114489518B (zh) * | 2022-03-28 | 2022-09-09 | 山东大学 | 测序数据质量控制方法及系统 |
CN115951936B (zh) * | 2023-01-17 | 2023-05-26 | 上海燧原科技有限公司 | 向量化编译程序的芯片适配方法、装置、设备及介质 |
CN117234514B (zh) * | 2023-11-08 | 2024-02-23 | 睿思芯科(深圳)技术有限公司 | 将标量化程序转换为向量化程序的方法、系统及相关设备 |
Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102231118A (zh) * | 2011-07-25 | 2011-11-02 | 中国科学技术大学 | 一种基于龙芯3a向量访存的编译优化方法 |
CN103049245A (zh) * | 2012-10-25 | 2013-04-17 | 浪潮电子信息产业股份有限公司 | 一种基于cpu多核平台的软件性能优化方法 |
Family Cites Families (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7016414B2 (en) * | 2001-10-19 | 2006-03-21 | Koninklijke Philips Electronics N.V. | Method and system for skipping decoding of overlaid areas of video |
US7802076B2 (en) * | 2004-06-24 | 2010-09-21 | Intel Corporation | Method and apparatus to vectorize multiple input instructions |
-
2013
- 2013-08-12 CN CN201310349628.8A patent/CN103440229B/zh active Active
Patent Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102231118A (zh) * | 2011-07-25 | 2011-11-02 | 中国科学技术大学 | 一种基于龙芯3a向量访存的编译优化方法 |
CN103049245A (zh) * | 2012-10-25 | 2013-04-17 | 浪潮电子信息产业股份有限公司 | 一种基于cpu多核平台的软件性能优化方法 |
Non-Patent Citations (2)
Title |
---|
MIC商用并行编程性能优化分析;王寅峰等;《深圳信息职业技术学院学报》;20130315;第11卷(第1期);全文 * |
龙芯3A多核处理器系统级性能优化与分析;孟小甫等;《计算机研究与发展》;20120215;全文 * |
Also Published As
Publication number | Publication date |
---|---|
CN103440229A (zh) | 2013-12-11 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN103440229B (zh) | 一种基于mic架构处理器的向量化优化方法 | |
Stephens et al. | The ARM scalable vector extension | |
Cummins et al. | Synthesizing benchmarks for predictive modeling | |
Ansel et al. | Petabricks: A language and compiler for algorithmic choice | |
Li et al. | A note on auto-tuning GEMM for GPUs | |
Wang et al. | FlexCL: An analytical performance model for OpenCL workloads on flexible FPGAs | |
Kennedy et al. | Telescoping languages: A strategy for automatic generation of scientific problem-solving systems from annotated libraries | |
Zheng et al. | AMOS: enabling automatic mapping for tensor computations on spatial accelerators with hardware abstraction | |
Rul et al. | An experimental study on performance portability of OpenCL kernels | |
Jain et al. | Efficient execution of quantized deep learning models: A compiler approach | |
Sharif et al. | ApproxHPVM: a portable compiler IR for accuracy-aware optimizations | |
Cassagne et al. | MIPP: a Portable C++ SIMD Wrapper and its use for Error Correction Coding in 5G Standard | |
Devic et al. | To pim or not for emerging general purpose processing in ddr memory systems | |
Sotomayor et al. | Automatic CPU/GPU generation of multi-versioned OpenCL kernels for C++ scientific applications | |
Saà-Garriga et al. | OMP2MPI: Automatic MPI code generation from OpenMP programs | |
Higuchi et al. | ClPy: a NumPy-compatible library accelerated with OpenCL | |
Lambert et al. | In-depth optimization with the OpenACC-to-FPGA framework on an Arria 10 FPGA | |
CN107729118A (zh) | 面向众核处理器的修改Java虚拟机的方法 | |
Pereira et al. | Extending OpenACC for efficient stencil code generation and execution by skeleton frameworks | |
Bramas | Inastemp: A novel intrinsics-as-template library for portable simd-vectorization | |
Singer et al. | SYCLops: A SYCL Specific LLVM to MLIR Converter | |
US20230116546A1 (en) | Method for compilation, electronic device and storage medium | |
Radhakrishnan et al. | Using coarrays to parallelize legacy Fortran applications: Strategy and case study | |
CN112083929B (zh) | 一种面向功率约束系统的性能-能耗协同优化方法及装置 | |
Fumero et al. | accull: An user-directed approach to heterogeneous programming |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |