CN103440229A - 一种基于mic架构处理器的向量化优化方法 - Google Patents

一种基于mic架构处理器的向量化优化方法 Download PDF

Info

Publication number
CN103440229A
CN103440229A CN2013103496288A CN201310349628A CN103440229A CN 103440229 A CN103440229 A CN 103440229A CN 2013103496288 A CN2013103496288 A CN 2013103496288A CN 201310349628 A CN201310349628 A CN 201310349628A CN 103440229 A CN103440229 A CN 103440229A
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.)
Granted
Application number
CN2013103496288A
Other languages
English (en)
Other versions
CN103440229B (zh
Inventor
吴庆
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Inspur Electronic Information Industry Co Ltd
Original Assignee
Inspur Electronic Information Industry Co Ltd
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by Inspur Electronic Information Industry Co Ltd filed Critical Inspur Electronic Information Industry Co Ltd
Priority to CN201310349628.8A priority Critical patent/CN103440229B/zh
Publication of CN103440229A publication Critical patent/CN103440229A/zh
Application granted granted Critical
Publication of CN103440229B publication Critical patent/CN103440229B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Landscapes

  • Devices For Executing Special Programs (AREA)

Abstract

本发明提供了一种基于MIC架构处理器的向量化优化方法,涉及算法数据依赖关系分析、算法向量化调整优化、向量化编译三个主要步骤,具体内容包括:算法的数据依赖分析、算法的向量化优化调整、编译器自动向量化技术、用户介入的向量化优化方法等。本发明提供的方法适用于MIC架构处理器平台的软件优化,指导软件开发人员以较短的开发周期,较低的开发成本,快速高效地对现有软件,尤其是核心算法进行向量优化改造,实现软件对向量处理器计算资源利用的最大化,最大限度地缩短软件运行时间,显著提高硬件资源利用率,提高软件的计算效率和软件整体性能。

Description

一种基于MIC架构处理器的向量化优化方法
技术领域
本发明涉及计算机高性能计算领域、科学计算领域,具体涉及一种基于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)向量化正确性验证,是验证向量化的正确性,体现在输出结果正确,误差在可以接受的范围内,具体实施步骤、方法细则如下:
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)测试环境
平台 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)向量化正确性验证。
重复以上过程,迭代调优,以实现循环向量化率最大化。 
3、 具体实施方式 
本发明的目的在于提供一种基于MIC处理器的向量化优化方法。
为了使本发明的目的、技术方案和优点更加清晰,下面结合附图和实施例,对本发明作以下详细说明。 
首先,简要介绍向量化处理原理及MIC处理器的向量处理单元VPU(Vector Process 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架构处理器的向量化优化实施步骤、方法细则如下: 
6) 循环向量化可行性分析。
编译器自动向量化过程中,可能收到某个循环无法被向量化的编译信息报告。很多时候无法向量化的原因都是循环间存在着变量依赖关系。 
通过阅读源代码,理解算法,必要时进行测试,确认代码中各循环结构间的数据依赖关系。进行数据依赖关系分析,是为了下一步对循环进行优化调整、并且介入编译器向量化编译行为。 
向量化处理的实质,就是将原本串行循环处理的计算任务,转换成若干循环同时处理的方式,因此,原理上,各次循环之间不能有前后的数据依赖关系。当然,在实际操作中,编译器可以通过设置私有变量、添加原子阻塞操作等方式,实现广义的向量化,这取决于向量化处理器硬件的设计及其所支持的指令集的设计。 
因此,循环可向量化的必要条件是: 
a) 循环之间不存在依赖关系。 
也就是说,所有的循环能同时  执行且互不干扰。例如: 
Figure 394668DEST_PATH_IMAGE001
等价于下面的操作:
Figure 771422DEST_PATH_IMAGE002
因此,这个循环是可以被向量化的。
再看一个例子: 
Figure 782104DEST_PATH_IMAGE003
无论如何,这个循环是不能被向量化的,因为a[i]在每次迭代中都依赖前一次迭代的结果。我们称这是一个交叉迭代的数据依赖或者“flow dependence”,这样的循环不能被编译器向量化。
b) 必须是内层循环。 
在一个嵌套的循环中,向量器只能尝试向量化最内层的循环,查看向量器的输出信息可以知道循环是否被向量化以及原因,如果影响性能的关键循环没有向量化,你可能需要做一些算法调整,比如调整嵌套循环的顺序。 
另外,除了具备以上必要条件外,还要注意以下几点: 
a) 向量化处理的数据类型尽量一致
需要向量化处理的语句,其包含的变量尽可能做到长度一致,即数据类型尽可能一致。如,尽量避免在同一表达式中同时出现单精度和双精度变量。
7)  向量化语句中尽可能避免函数调用:表达式中调用函数,会增加语句的复杂度,干扰编译器实施自动向量化,即使是标准的数学函数,也要尽量避免,如果一定要使用,也要尽可能使函数精度与变量精度一致,如: 
Figure 750060DEST_PATH_IMAGE004
8) 向量化优化
采用以下多种方法,实现循环的向量化处理。
a)  编译器自动向量化 
编译器自动向量化依赖于编译器自身的能力来消除内存引用二义性。Intel C/C++编译器,默认向量化编译选项为-vec,即默认情况下向量化是打开的,若关闭向量化可以在编译选项中添加-no-vec。编译器在对源代码进行编译时,会输出编译信息/报告,某些编译器有多个编译信息输出级别,其编译信息输出级别可使用-vec-report  level控制,见下表:
-vec-report[level] 含义
0 不显示诊断信息。
1 只显示已向量化的循环(默认值)。
2 显示已向量化和未向量化的循环。
3 显示已向量化和未向量化的循环以及数据依赖信息。
4 只显示未向量化的循环。
5 显示未向量化的循环以及数据依赖信息。
通过编译器输出的编译信息报告,可以了解编译的详细细节,比如某个循环是否被向量化,向量化失败的原因等,这些信息可以为向量优化提供依据和指导。
b)     基于向量化编译指示的向量化 
向量化编译指示,可以更好地指导编译器进行数据依赖分析,从而更好地向量化代码。
例如__declspec(align(n)) 声明能够使编译器克服硬件对齐的限制。restrict修饰词和自动向量化提示解决了由于作用范围、数据依赖和二义性等产生的问题。SIMD编译指示使得最内层的循环被强制向量化。使用向量化编译指令是有风险的,使用的前提条件是程序员必须确保不存在数据依赖。 
Intel编译器向量化编译指示如下表: 
Figure 846192DEST_PATH_IMAGE005
其中SIMD 编译指示有五个可供选择的子句来指导编译器执行何种向量化。恰当地使用这些子句,会让编译器获得足够的信息来产生正确的向量化代码。
(6)       vectorlength(num1, num2, …, numN) 
指导向量优化单元可以从指定的若干向量长度(VL)num1, num2, … , numN 中选择来向量化循环。对于选定的VL,向量循环的每一次执行的计算工作相当于原来标量循环VL 次执行的计算工作。多个向量长度子句会合并成一个集合。
(7)private(expr1, expr2, …, exprN) 
指导向量优化单元使得这些左值(L-value)表达式expr1, exper2, ..., exprN 对于每一次循环都是私有的。多个private 子句会合并成一个集合。左值表达式的初值将被广播到所有的私有子句,除非编译器能够判定初值未在循环体内使用;左值表达式的终值也会被从最后一次执行的循环体复制出来, 除非编译器能够判定终值未在循环后被使用。
(8)linear(var1:step1, var2:step2, …, varN:stepN) 
指导编译器每一次标量循环的执行时,var1 的值增加step1, var2 的值增加step2, 依此类推。相应地,每次向量循环的执行,使得这些变量的值分别增加VL*step1,
VL*step2, …, VL*stepN。多个linear 子句会被合并成一个集合。如果var 被赋予两个或多个step 值,会产生一个编译错误。
(9)reduction(oper:var1,var2,…,varN) 
指导编译器对于变量var1, var2, …, varN 执行向量化规约操作oper。一个SIMD 编译指示可以有多个归约子句,执行相同或者不同的操作。如果一个变量var 与两个或多个不同的归约操作oper 有关, 会产生一个编译错误。
(10)[no]assert 
指导编译器当向量化失败时是否报错,缺省是不报错。一个SIMD 编译指令不应该存在多个该子句,否则会产生一个编译错误。
下面,列举一个典型实例说明基于向量化编译指示的向量化。为了向量化一个包含潜在依赖关系的循环,用户经过数据依赖分析后,确认其不存在循环间数据依赖,可加上#pragma ivdep提示编译器忽略存在的数据依赖关系,示例程序片段如下: 
Figure 354533DEST_PATH_IMAGE006
当向量化以上代码段中的循环时,编译器会认为该循环存在循环间依赖,即第j次循环依赖第j+k次循环的结果,这种依赖关系称为交叉迭代依赖。而如果我们确定k>16,超过MIC VPU的向量处理宽度,循环间就不存在实际意义上的数据依赖,加上#pragma ivdep指示编译器忽略数据的依赖关系并尝试进行向量化,甚至可以使用#pragma simd强制向量化该循环。如果L<k<16,那么可以使用#pragma simd vectorlength(L)强制向量化该循环,并且能保证结果的正确性。
9)  算法向量化改造 
如果采用以上两种向量化方式,还有部分循环无法实现向量化,可以在数据依赖分析的基础上,对算法进行深度优化改进。主要的向量化改造方法有:
a)  调整嵌套循环的顺序
自动向量化只能对嵌套中的最内层的循环进行向量化,然而内层循环向量化效果未必最好,我们可以通过调整嵌套循环的顺序达到更好的向量化效果,如调整之后的向量化可以实现更好的连续访问,如下面的代码所示,B代码的向量化效果比A的好。
b)  
Figure 485300DEST_PATH_IMAGE007
c)  拆分循环
在某些情况下,除了最内层的循环比较耗时外,其它不在最内层循环的代码也比较耗时,而这部分代码是无法自动向量化的,为此,我们可以采取拆分循环的方法实现更多的自动向量化,下面通过一段伪代码说明其使用方法。
Figure 624158DEST_PATH_IMAGE008
假设上面的代码中循环无数据依赖,由于rand函数无法向量化,从而导致整个循环无法向量化,我们可以把一个循环拆成两个循环的方法达到第二个for循环(主要耗时的)实现向量化的目的,代码如下: 
Figure 128957DEST_PATH_IMAGE009
另一个例子:
Figure 378673DEST_PATH_IMAGE010
假设上面的代码中两层循环均无数据依赖,除了内层循环for(j=0; j<M; j++)比较耗时,对于s的求解也很耗时,然而求解s的部分是无法自动向量化的。我们可以通过拆分外层的循环做到更好地自动向量化效果,修改后的伪代码如下:
Figure 363947DEST_PATH_IMAGE011
}通过对循环的拆分,我们可以使更多的代码自动向量化,可以获取更好的向量化性能。
d)  手写SIMD指令向量化 
向量化的层次如下图所示,越往上的级别,使用的语言越低级,编程越复杂,但控制的灵活性越好,理论上性能也越高。相反的,越往下的级别,编程越容易,但性能可能不是最理想。
第一代Intel MIC产品为KNC(Knights Corner),Knights Corner Instructions是KNC支持的SIMD指令的总称。可以看作是类似于SSE、AVX等的指令集。通过使用Knights Corner指令,可以细粒度地控制向量化运算。 
Knights Corner Instructions分类: 
(3)    Knights Corner指令(Knights Corner instruction)是指具体的SIMD指令,是汇编指令集中关于SIMD的子集。
(4)    内建Knights Corner(Intrinsics of Knights Corner)是对Knights Corner指令的封装(几乎涉及到所有指令),可以认为这些函数和数据类型是C/C++的内建类型。 
(5)    Knights Corner类库(Knights Corner Class Libraries)是为了方便使用Knights Corner指令而做的封装,可以让程序员尽量简单地使用SIMD指令,介于引语方式和SIMD代码之间。其支持整型和浮点型数据。 
下面通过单精度浮点向量加的例子说明三者的区别: 
Figure 947692DEST_PATH_IMAGE013
通过上面的例子可以看出使用类库的方式非常简单,能够以最类似于标量的方式(把数组看成变量),进行向量化改造。而直接使用内建Knights Corner则更接近常规的思维方式,将两个数组通过向量化函数进行运算,当然,其代码要比使用类库方式复杂一些,但由于减少了封装和调用,因此性能也会略有提高。而内联汇编则是最难阅读的,由于最贴近底层,因而执行效率也最高,只是编程的成本也是最高的。在实际的SIMD指令编写中,我们一般采用内建Knights Corner的方式。
下面我们通过一个向量加的示例说明SIMD指令的使用方法。 
Figure DEST_PATH_IMAGE014
SIMD指令与汇编指令类似,可读性较差,并且严重依赖于硬件,可移植性差。因此,SIMD指令一般选择性使用,如代码量较少,计算却十分密集的地方。 
10)  向量化正确性验证。 
编译源代码,然后运行程序,检查程序的输出结果,验证向量化的正确性。 
向量化可能会带来精度损失,必要时可以通过编译器的-fp-model选项,调整向量化的精度。 
11)  迭代调优。 
重复以上过程,以实现循环向量化率最大化,从而使MIC处理器VPU的计算性能尽可能发挥出来。 
4、性能测试及分析 
将该方法应用于一个典型的高性能运算案例——矩阵乘法。
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)  性能测试结果分析
利用该方法对矩阵乘法应用案例进行向量化改造后,显著地提升了该模块的运行效率,获得了较高的性能加速比。
5、总结 
由本发明的技术方案可见,本发明提供了一种基于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)编译器自动向量化
编译器自动向量化依赖于编译器自身的能力来消除内存引用二义性,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模块的运行效率,获得了较高的性能加速比。
2.根据权利要求1所述的方法,其特征在于,编译过程中所使用的编译器,是支持MIC架构及其指令集的任意编译器,该编译器生成的目标代码,直接或通过后续编译处理后,能够运行于MIC架构处理器。
CN201310349628.8A 2013-08-12 2013-08-12 一种基于mic架构处理器的向量化优化方法 Active CN103440229B (zh)

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 true CN103440229A (zh) 2013-12-11
CN103440229B 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)

Cited By (20)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN104112264A (zh) * 2014-07-15 2014-10-22 东南大学 一种基于局部方差图像增强的优化方法
CN104346318A (zh) * 2014-10-15 2015-02-11 中国人民解放军国防科学技术大学 面向通用多核dsp的矩阵乘加速方法
US20150277877A1 (en) * 2014-03-25 2015-10-01 Nec Laboratories America, Inc. Compiler optimization for many integrated core processors
CN105204822A (zh) * 2015-10-27 2015-12-30 浪潮(北京)电子信息产业有限公司 一种基于mic协处理器的多数据流处理方法
CN105242907A (zh) * 2015-09-10 2016-01-13 西安交通大学 Arm二进制代码的neon向量化转换方法
WO2016061911A1 (zh) * 2014-10-20 2016-04-28 浪潮电子信息产业股份有限公司 一种基于mic实现聚类算法的方法及装置
CN105808310A (zh) * 2016-04-01 2016-07-27 浪潮电子信息产业股份有限公司 一种适用于大规模并行软件GTC的核心模块Pushe的高效向量化方法
CN106959937A (zh) * 2017-03-30 2017-07-18 中国人民解放军国防科学技术大学 一种面向gpdsp的反卷积矩阵的向量化实现方法
CN107193535A (zh) * 2017-05-16 2017-09-22 中国人民解放军信息工程大学 基于simd扩展部件的嵌套循环向量并行的实现方法及其装置
CN108416056A (zh) * 2018-03-21 2018-08-17 哈工大大数据(哈尔滨)智能科技有限公司 基于条件包含依赖的相关性学习方法、装置、设备及介质
CN110673877A (zh) * 2019-08-22 2020-01-10 成都信息工程大学 一种基于手动向量化的并行计算方法
CN110795106A (zh) * 2019-10-30 2020-02-14 中国人民解放军战略支援部队信息工程大学 程序向量化过程中动静结合的内存别名分析处理方法及装置
CN111428327A (zh) * 2018-12-24 2020-07-17 深圳市中兴微电子技术有限公司 一种指令硬件架构的构建方法、装置及存储介质
CN112947932A (zh) * 2021-02-24 2021-06-11 上海商汤智能科技有限公司 对编译过程中的向量化进行优化的方法、装置及电子设备
CN113704687A (zh) * 2020-05-21 2021-11-26 杭州海康威视数字技术股份有限公司 一种张量计算运行方法、装置及运算系统
CN114489518A (zh) * 2022-03-28 2022-05-13 山东大学 测序数据质量控制方法及系统
CN114637388A (zh) * 2022-03-18 2022-06-17 中国科学院计算技术研究所 面向数据流处理器的功耗控制方法及装置
WO2022126885A1 (en) * 2020-12-17 2022-06-23 Huawei Technologies Co., Ltd. Method and apparatus for retaining optimal width vector operations in arbitrary/flexible vector width architecture
CN115951936A (zh) * 2023-01-17 2023-04-11 上海燧原科技有限公司 向量化编译程序的芯片适配方法、装置、设备及介质
CN117234514A (zh) * 2023-11-08 2023-12-15 睿思芯科(深圳)技术有限公司 将标量化程序转换为向量化程序的方法、系统及相关设备

Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20030076885A1 (en) * 2001-10-19 2003-04-24 Koninklijke Philips Electronics N.V. Method and system for skipping decoding of overlaid areas of video
US20050289529A1 (en) * 2004-06-24 2005-12-29 Yoav Almog Method and apparatus to vectorize multiple input instructions
CN102231118A (zh) * 2011-07-25 2011-11-02 中国科学技术大学 一种基于龙芯3a向量访存的编译优化方法
CN103049245A (zh) * 2012-10-25 2013-04-17 浪潮电子信息产业股份有限公司 一种基于cpu多核平台的软件性能优化方法

Patent Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20030076885A1 (en) * 2001-10-19 2003-04-24 Koninklijke Philips Electronics N.V. Method and system for skipping decoding of overlaid areas of video
US20050289529A1 (en) * 2004-06-24 2005-12-29 Yoav Almog Method and apparatus to vectorize multiple input instructions
CN102231118A (zh) * 2011-07-25 2011-11-02 中国科学技术大学 一种基于龙芯3a向量访存的编译优化方法
CN103049245A (zh) * 2012-10-25 2013-04-17 浪潮电子信息产业股份有限公司 一种基于cpu多核平台的软件性能优化方法

Non-Patent Citations (2)

* Cited by examiner, † Cited by third party
Title
孟小甫等: "龙芯3A多核处理器系统级性能优化与分析", 《计算机研究与发展》 *
王寅峰等: "MIC商用并行编程性能优化分析", 《深圳信息职业技术学院学报》 *

Cited By (31)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20150277877A1 (en) * 2014-03-25 2015-10-01 Nec Laboratories America, Inc. Compiler optimization for many integrated core processors
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 东南大学 一种基于局部方差图像增强的优化方法
CN104346318A (zh) * 2014-10-15 2015-02-11 中国人民解放军国防科学技术大学 面向通用多核dsp的矩阵乘加速方法
CN104346318B (zh) * 2014-10-15 2017-03-15 中国人民解放军国防科学技术大学 面向通用多核dsp的矩阵乘加速方法
WO2016061911A1 (zh) * 2014-10-20 2016-04-28 浪潮电子信息产业股份有限公司 一种基于mic实现聚类算法的方法及装置
CN105242907A (zh) * 2015-09-10 2016-01-13 西安交通大学 Arm二进制代码的neon向量化转换方法
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的反卷积矩阵的向量化实现方法
CN106959937A (zh) * 2017-03-30 2017-07-18 中国人民解放军国防科学技术大学 一种面向gpdsp的反卷积矩阵的向量化实现方法
CN107193535B (zh) * 2017-05-16 2019-11-08 中国人民解放军信息工程大学 基于simd扩展部件的嵌套循环向量并行的实现方法及其装置
CN107193535A (zh) * 2017-05-16 2017-09-22 中国人民解放军信息工程大学 基于simd扩展部件的嵌套循环向量并行的实现方法及其装置
CN108416056B (zh) * 2018-03-21 2020-12-04 哈工大大数据(哈尔滨)智能科技有限公司 基于条件包含依赖的相关性学习方法、装置、设备及介质
CN108416056A (zh) * 2018-03-21 2018-08-17 哈工大大数据(哈尔滨)智能科技有限公司 基于条件包含依赖的相关性学习方法、装置、设备及介质
CN111428327A (zh) * 2018-12-24 2020-07-17 深圳市中兴微电子技术有限公司 一种指令硬件架构的构建方法、装置及存储介质
CN110673877A (zh) * 2019-08-22 2020-01-10 成都信息工程大学 一种基于手动向量化的并行计算方法
CN110673877B (zh) * 2019-08-22 2020-09-01 成都信息工程大学 一种基于手动向量化的并行计算方法
CN110795106B (zh) * 2019-10-30 2022-10-04 中国人民解放军战略支援部队信息工程大学 程序向量化过程中动静结合的内存别名分析处理方法及装置
CN110795106A (zh) * 2019-10-30 2020-02-14 中国人民解放军战略支援部队信息工程大学 程序向量化过程中动静结合的内存别名分析处理方法及装置
CN113704687A (zh) * 2020-05-21 2021-11-26 杭州海康威视数字技术股份有限公司 一种张量计算运行方法、装置及运算系统
CN113704687B (zh) * 2020-05-21 2024-04-05 杭州海康威视数字技术股份有限公司 一种张量计算运行方法、装置及运算系统
WO2022126885A1 (en) * 2020-12-17 2022-06-23 Huawei Technologies Co., Ltd. Method and apparatus for retaining optimal width vector operations in arbitrary/flexible vector width architecture
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 中国科学院计算技术研究所 面向数据流处理器的功耗控制方法及装置
CN114489518A (zh) * 2022-03-28 2022-05-13 山东大学 测序数据质量控制方法及系统
CN115951936A (zh) * 2023-01-17 2023-04-11 上海燧原科技有限公司 向量化编译程序的芯片适配方法、装置、设备及介质
CN117234514A (zh) * 2023-11-08 2023-12-15 睿思芯科(深圳)技术有限公司 将标量化程序转换为向量化程序的方法、系统及相关设备
CN117234514B (zh) * 2023-11-08 2024-02-23 睿思芯科(深圳)技术有限公司 将标量化程序转换为向量化程序的方法、系统及相关设备

Also Published As

Publication number Publication date
CN103440229B (zh) 2017-11-10

Similar Documents

Publication Publication Date Title
CN103440229A (zh) 一种基于mic架构处理器的向量化优化方法
Stephens et al. The ARM scalable vector extension
Tang et al. The pochoir stencil compiler
Ansel et al. Petabricks: A language and compiler for algorithmic choice
Rul et al. An experimental study on performance portability of OpenCL kernels
Porpodas et al. PSLP: Padded SLP automatic vectorization
US9009689B2 (en) Speculative compilation to generate advice messages
Deniz et al. Minime: Pattern-aware multicore benchmark synthesizer
Mustafa A survey of performance tuning techniques and tools for parallel applications
Lambert et al. In-depth optimization with the OpenACC-to-FPGA framework on an Arria 10 FPGA
Nobre et al. Aspect-driven mixed-precision tuning targeting gpus
Zhong et al. Using advanced vector extensions avx-512 for mpi reductions
Ashraf et al. AAP4All: An Adaptive Auto Parallelization of Serial Code for HPC Systems.
Christofi et al. Exploring HPC parallelism with data-driven multithreating
Han et al. Polyhedral-Based Compilation Framework for In-Memory Neural Network Accelerators
Custers Algorithmic species: Classifying program code for parallel computing
Akimova et al. Algorithm of Automatic Parallelization of Generalized Matrix Multiplication
Mukunoki et al. Minimal-precision computing for high-performance, energy-efficient, and reliable computations
Cramer et al. Evaluating the performance of OpenMP offloading on the NEC SX-Aurora TSUBASA vector engine
Lupo et al. Enhancing regional ocean modeling simulation performance with the Xeon Phi architecture
Biookaghazadeh et al. Characterizing Loop Acceleration in Heterogeneous Computing
Giacomoni et al. Toward a toolchain for pipeline parallel programming on CMPs
Nobre et al. Beyond Polyhedral Analysis of OpenStream Programs
Gelis et al. Parallel programming for physicists
Zhang Rendering and Image Processing for Micro Lithography on Xeon Phi Knights Landing Processor

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