一种基于龙芯3a的单精度矩阵乘法优化方法

文档序号:6559405阅读:219来源:国知局
专利名称:一种基于龙芯3a的单精度矩阵乘法优化方法
技术领域
本发明属于电数字数据处理技术领域,具体涉及基于龙芯3A的单精度矩阵乘法的优化方法。
背景技术
龙芯3A是中国第一个具有完全自主知识产权的四核中央处理器(CPU)。在高性能计算领域,龙芯3A需要基础线性代数子程序库的支持。龙芯3A上能够使用的较优的基础线性代数子程序库是美国德克萨斯大学奥斯汀分校超级计算中心高性能计算组开发的基础线性代数子程序库(GotoBLAQ。德克萨斯大学奥斯汀分校超级计算中心高性能计算组开发的基础线性代数子程序库(GotoBLAQ通过使用矩阵分块、数据拷贝、循环展开和指令调度等优化技术,实现了高效的单精度矩阵乘法。龙芯3A拥有1 位访存、并行单精度浮点等特有指令,但由于德克萨斯大学奥斯汀分校超级计算中心高性能计算组开发的基础线性代数子程序库(GotoBLAQ并不是针对龙芯3A的特点所做的专门优化,因此它所采用的单精度矩阵乘法在龙芯3A平台上执行的性能并不高。

发明内容
本发明提出一种基于龙芯3A的单精度矩阵乘法优化方法,以克服现有技术的上述缺陷,达到在龙芯3A平台上单精度矩阵乘法的高效实现。本发明基于龙芯3A的单精度矩阵乘法优化方法,先将龙芯3A的两个单精度源矩阵按分块大小分别不大于二级缓存的原则划分成为两个子矩阵,然后将分块形成的子矩阵块拷贝到一个连续的地址空间中,再通过使用龙芯3A的32位访存指令、单精度浮点乘加指令和预取指令的矩阵乘法核心计算代码来完成子矩阵与子矩阵的乘法;其特征在于所述将龙芯3A的两个单精度源矩阵按分块大小分别不大于二级缓存的原则划分采取分别不大于一级缓存一半和不大于二级缓存一半的原则划分成为两个子矩阵;在所述龙芯3A的32 位访存指令、单精度浮点乘加指令和预取指令的矩阵乘法核心计算代码中采用龙芯3A的 128位访存指令和并行单精度浮点指令,并采用两倍的运算数据集大小减去运算数据单元大小预取地址计算方式来对数据进行预取;具体操作步骤如下第一步、数据分块并拷贝步骤先将龙芯3A的两个单精度源矩阵分块,使第一个源矩阵的子块大小不大于龙芯 3A 一级缓存容量的一半,第二个源矩阵的子块大小为不大于龙芯3A 二级缓存容量的一半, 然后将两个子块分别拷贝到互相连续的两个地址空间中;第二步、核心计算代码编写步骤通过使用1 位访存指令,每次将4个单精度浮点数取到2个64位的浮点寄存器中;使用低高位合并指令plu. PS将存于寄存器高32位的单精度浮点数提取出来,使用并行单精度浮点乘加指令madd. ps实现并行单精度浮点乘加运算;循环展开度设为4*4,即每次从两个子块中各取4个单精度浮点数,两两分别相乘后得到16个结果累加到目标矩阵中;指令调度中,由4条指令组成一个小组,每个小组包含浮点操作指令2条,取数指令和空操作指令各一条或空操作指令2条,由5个小组组成一个大组,浮点计算需要用的操作数全部提前2个大组通过1 位访存指令和低高位合并指令放到指定寄存器中;在核心计算代码的最开头,对结果矩阵和第二个源矩阵子块进行预取,其中结果矩阵的预取地址设为两倍的运算数据集大小减去运算数据单元大小,第二个源矩阵子块的预取地址设为运算数据集大小,预取指令的频率等于高速缓冲存储器(Cache)行的大小除以计算数据集的大小。本发明基于龙芯3A的单精度矩阵乘法优化方法还可以将所述数据分块并拷贝步骤中子块拷贝到连续空间的方法进一步改进为将两个源矩阵数据分别以龙芯3A —级缓存容量的1/4为间隔拷贝到目标地址空间中,使两个子块的拷贝目标地址所对应的一级缓存地址不在同一组。与现有技术相比较,本发明提出的这种基于龙芯3A的单精度矩阵乘法优化方法, 通过使用1 位访存和并行单精度浮点等龙芯3A的特有指令,使取数和浮点部件运算效率有所提高;由于本发明根据龙芯3A指令流水特点,在核心计算代码中巧妙地排列指令顺序,使浮点运算部件基本上能够满负荷运转;由于本发明改进了预取地址计算方式,克服了地址非对齐数据预取无效的问题,从而使地址非对齐的单精度矩阵乘法执行效率达到接近于地址对齐的单精度矩阵乘法。采用本发明方法优化后的单精度矩阵乘法的运算速度比德克萨斯大学奥斯汀分校超级计算中心高性能计算组开发的基础线性代数子程序库 (GotoBLAS)版本2-1. 07中的实现平均提高了 90%以上。
具体实施例方式实施例1 本发明基于龙芯3A的单精度矩阵乘法优化方法,先将龙芯3A的两个单精度源矩阵按分块大小分别不大于二级缓存的原则划分成为两个子矩阵采取分别不大于一级缓存一半和不大于二级缓存一半的原则划分成为两个子矩阵;在龙芯3A的32位访存指令、单精度浮点乘加指令和预取指令的矩阵乘法核心计算代码中采用龙芯3A的1 位访存指令和并行单精度浮点指令,并采用两倍的运算数据集大小减去运算数据单元大小预取地址计算方式来对数据进行预取。本实施例中采取了先将龙芯3A的两个单精度源矩阵划分成分块大小分别为 64*128和128*10M的两个子矩阵,然后将划分得到的子矩阵块拷贝到一个连续的地址空间中,再通过针对龙芯3A平台特性编写的核心计算代码来完成子矩阵与子矩阵的乘法。具体步骤列举如下第一步、数据分块并拷贝步骤先将龙芯3A的两个单精度源矩阵分块使第一个源矩阵的子块大小不大于龙芯 3A—级缓存容量的一半,本实施例中第一个源矩阵的子块大小取64*1观;第二个源矩阵的子块大小不大于二级缓存一半,本实施例中第二个源矩阵的子块大小取128*10M ;然后将两个子块拷贝到连续的空间中。为减少缓存冲突,还可以采取将两个源矩阵数据分别以龙芯3A—级缓存容量的 1/4为间隔拷贝到目标地址空间中,使两个子块的拷贝目标地址所对应的一级缓存地址不
在同一组。为了平衡处理器运算速度和主存储器访问速度之间的差异,基于程序的局部性原理,现有的处理器与存储器之间都有高速缓冲存储器(Cache)。当中央处理器(CPU)访问存储器时,如果需要的数据高速缓冲存储器(Cache)命中,此时访存能很快完成;如果需要的数据在高速缓冲存储器(Cache)不命中,中央处理器(CPU)需要从下一级存储器读取数据, 这会带来很大的延时,严重影响程序性能。数据分块技术就是通过重新组织数据的访问顺序,减小高速缓冲存储器(Cache)的失效率来提高程序性能的方法。龙芯3A的高速缓冲存储器(Cache)分为两级,一级高速缓冲存储器(Cache)的延迟为4拍,二级高速缓冲存储器(Cache)的延迟为15 25拍。由于受到寄存器数量的限制,要想减少流水线的中断和停顿,单精度矩阵乘法的核心计算部分的数据采取从一级高速缓冲存储器(Cache)中获得的方法。为了使核心计算部分的数据驻留在一级高速缓冲存储器(Cache),子数据块大小不能超过一级高速缓冲存储器(Cache)的大小。单精度矩阵乘法拥有局部性原理的是矩阵A和矩阵B的数据,矩阵C的数据是流式的,因此矩阵C的数据没有必要驻留在一级高速缓冲存储器(Cache)中。龙芯3A的一级高速缓冲存储器(Cache) 总共大小为64KB,第一个源矩阵的子块应尽量大但不超过一级高速缓冲存储器(Cache) — 半,剩下的用于第二个源矩阵子块的部分数据存储,这样可以减少数据拷贝的代价,同时可以避过两个源矩阵子块过多的冲突失效。龙芯3A平均每个处理器核分到一块二级高速缓冲存储器(Cache),大小为1MB,因此将一块二级高速缓冲存储器(Cache)的5 12KB用于B 矩阵子块的存储。龙芯3A的高速缓冲存储器(Cache)替换策略是随机替换,为了减少A矩阵子块和B矩阵子块的冲突失效,本发明中还提出了可采取地址交错的方式存储矩阵A和矩阵B,即将A矩阵子块和B矩阵子块交替存储,从而可保证A矩阵子块和B矩阵子块不在一级高速缓冲存储器(Cache)的同一组当中。第二步、核心计算代码编写步骤通过使用1 位访存指令,每次将4个单精度浮点数取到2个64位的浮点寄存器中。一般取数指令一次只能取64位的数据,然而龙芯3A拥有1 位访存指令,因此一次可以取到1 位的数据,即4个单精度浮点数。这样不但可以减少指令数量,还可以加快访存速度。使用低高位合并指令plu. ps将存于寄存器高32位的单精度浮点数提取出来,使用并行单精度浮点乘加指令madd. ps实现并行单精度浮点乘加运算。一个单精度浮点数为4个字节,即32位,而龙芯3A的浮点寄存器大小为64位,因此普通的单精度矩阵乘法实现中,每次运算只用到了 64位寄存器的一半。龙芯3A浮点协处理器支持并行单精度(PQ浮点运算,因此本发明使用这些并行单精度浮点运算指令来充分使用64位的寄存器,把单精度矩阵乘法的理论峰值提高一倍。本实施例中实现并行单精度(PQ浮点加速的方法是第一步使用普通取数指令将结果矩阵的数据取到寄存器中,并使用低位合并指令pll. ps将两个32位单精度数据合并到一个64位的寄存器中;第二步使用1 位访存指令将矩阵A和B的数据取到寄存器中,并使用低高位合并指令plu. ps将存于寄存器高32位的单精度浮点数提取出来;第三步是使用并行单精度浮点乘加指令madd. ps实现并行单精度浮点乘加运算,同时将下一组要使用的矩阵A和B的数据取到寄存器中,并使用低高位合并指令plu. ps将存于寄存器高32 位的单精度浮点数提取出来;第四步是使用低高位合并指令Plu. ps将存于寄存器高32位的单精度浮点数,即计算结果提取出来,使用普通存数指令写回结果。其中第三步是反复进行的,根据被计算矩阵的大小来确定循环的次数。循环展开中,因浮点寄存器数量有限,故选择循环展开度为4*4,即每次从两个子块中各取4个单精度浮点数,两两分别相乘后得到16个结果累加到目标矩阵中,这样的展开粒度不仅满足了浮点寄存器数量的限制、减少了访存次数,还提高了指令调度的灵活性。指令调度中,由4条指令组成一个小组,每个小组包含浮点操作指令2条,取数指令和空操作指令各一条或空操作指令2条;再由每5个小组组成一个大组,为了保证浮点计算单元需要的数据能够及时供应上,浮点计算需要用的操作数要提前通过1 位访存指令和低高位合并指令放到指定寄存器中,本实施例中采用了提前2个大组进行取数的方式。这里的浮点操作指令即为并行单精度浮点乘加指令madd. ps或低高位合并指令 plu.ps,取数指令即为1 位访存指令gslqcl。1 位访存指令取的数据为本大组后第2 个大组需要使用的数据,并行单精度浮点乘加指令使用的数据为本大组之前第2个大组取得的数据。当每个小组不满4条指令时就用空操作来补充,其目的是保证每拍发射的四条指令不会发生功能部件的竞争。第1、2、4和5小组都是包括1条1 位访存指令、1条空操作指令和2条并行单精度浮点乘加指令;第3个组包括2条空操作指令和2条低高位合并指令,用于将取到的数据组合成计算所需的形式,就是将源寄存器的高32位复制到目标寄存器的高32位和低32位中。各小组代码具体列举如下gslqcl X2, X0,4 (a_offset)nopmadd. ρs COO, COO, NXO, NYOmadd. ρs C20, C20, NX2, NYOgslqcl Y2, Y0,4 (b_offset)nopmadd. ps C02,C02,NXO,NY2madd. ps C22, C22, NX2, NY2nopnopplu. ps NB1, NBO, NBOplu. ps NB3, NB2, NB2nopnopmadd. ps COl,COl,NXO,NYlmadd. ps C21,C21,NX2,NY1nop
nopmadd. ps C03, C03, NXO, NY3madd. ps C23, C23, NX2, NY3在核心计算代码的最开头,对结果矩阵和第二个源矩阵子块进行预取,其中结果矩阵的预取地址设为两倍的运算数据集大小减去运算数据单元大小,第二个源矩阵子块的预取地址设为运算数据集大小。预取是一种有效的隐藏访存延迟的技术,它利用内存的空闲带宽,通过显式的预取指令,使数据在实际使用之前从内存移到高速缓冲存储器(Cache)中,将访存的失效开销与计算时间重叠,以减小高速缓冲存储器(Cache)失效所带来的性能损失。数据预取的一个关键问题是预取地址的计算,错误的预取地址不但不能隐藏访存开销,还会因为指令数量和无效访存的增加而降低程序性能。矩阵乘法属于比较规整的运算,预取地址很容易计算,常用预取地址计算方法是用运算数据集首地址加上运算数据集大小,第二个源矩阵子块的预取就可以采用这种方式。这里所说的运算数据集指的是一个将被取到寄存器进行运算的不超过高速缓冲存储器(Cache)行大小的连续数据集,但由于这些数据并不一定处于同一个高速缓冲存储器(Cache)行中一旦被预取的数据集不在一个高速缓冲存储器(Cache)行中,就有可能出现无效预取。设运算数据集的首地址距离前一个高速缓冲存储器(Cache)行边界12字节,预取数据集的首地址距离运算数据集的首地址A有16字节,每个数据集有4个数据,每个数据单元4个字节。运算数据集在做运算的过程中,会发送预取指令来预取预取数据集首地址所在高速缓冲存储器(Cache)行的所有数据。预取数据集首地址在运算数据集所在的高速缓冲存储器(Cache)行中,也就是说在运算数据集取数的过程将会把预取数据集首地址所在的高速缓冲存储器(Cache)行取到高速缓冲存储器(Cache)中,即预取数据集首地址的数据预取将是无效预取,对程序性能的提升没有任何帮助。为了避免非高速缓冲存储器(Cache)行对齐数据的无效预取,本发明中提出了新的预取地址计算方法公式PA = CACDS+2*sizeof(CDS)-sizeof(DU) (1)即预取地址PA等于运算数据集的首地址CA⑶S加上两倍的运算数据集⑶S大小, 再减去一个数据单元DU大小。一个单精度浮点数的大小为4字节,单精度矩阵乘法的预取数据集和运算数据集的大小都是4个单精度浮点数,因此预取地址为运算数据集的首地址加上28字节。当运算数据集小于高速缓冲存储器(Cache)大小时,即使使用如上的预取地址计算方式,还是会产生冗余的预取指令,因此可以调整预取指令的频率,没有必要每个运算数据集都对应一个预取指令。由此,本发明给出一种预取指令频率的计算方法公式PF = sizeof (CL)/sizeof (CDS) (2)即预取指令的频率PF等于高速缓冲存储器(Cache)行CL的大小除以计算数据集 CDS的大小。由于在龙芯3A体系结构下一次可以预取32字节,单精度矩阵乘法的运算数据集为16字节,因此预取频率为0. 5。性能及效果分析综合使用本发明的上述优化技术以后,在龙芯3A体系结构下,中央处理器(CPU)主频为825M,内存主频为200M,测试规模为100到2000之间,采用本发明方法优化后的单精度矩阵乘法的运算速度比德克萨斯大学奥斯汀分校超级计算中心高性能计算组开发的基础线性代数子程序库(GotoBLAQ版本2-1. 07中的实现平均提高了 90%以上。
权利要求
1.一种基于龙芯3A的单精度矩阵乘法优化方法,先将龙芯3A的两个单精度源矩阵按分块大小分别不大于二级缓存的原则划分成为两个子矩阵,然后将分块形成的子矩阵块拷贝到一个连续的地址空间中,再通过使用龙芯3A的32位访存指令、单精度浮点乘加指令和预取指令的矩阵乘法核心计算代码来完成子矩阵与子矩阵的乘法;其特征在于所述将龙芯3A的两个单精度源矩阵按分块大小分别不大于二级缓存的原则划分采取分别不大于一级缓存一半和不大于二级缓存一半的原则划分成为两个子矩阵;在所述龙芯3A的32位访存指令、单精度浮点乘加指令和预取指令的矩阵乘法核心计算代码中采用龙芯3A的1 位访存指令和并行单精度浮点指令,并采用两倍的运算数据集大小减去运算数据单元大小预取地址计算方式来对数据进行预取;具体操作步骤如下第一步、数据分块并拷贝步骤先将龙芯3A的两个单精度源矩阵分块,使第一个源矩阵的子块大小不大于龙芯3A — 级缓存容量的一半,第二个源矩阵的子块大小为不大于龙芯3A 二级缓存容量的一半,然后将两个子块分别拷贝到连续的两个地址空间中;第二步、核心计算代码编写步骤通过使用1 位访存指令,每次将4个单精度浮点数取到2个64位的浮点寄存器中;使用低高位合并指令将存于寄存器高32位的单精度浮点数提取出来,使用并行单精度浮点乘加指令实现并行单精度浮点乘加运算;循环展开度设为4*4,即每次从两个子块中各取4个单精度浮点数,两两分别相乘后得到16个结果累加到目标矩阵中;指令调度中,由4条指令组成一个小组,每个小组包含浮点操作指令2条,取数指令和空操作指令各一条或空操作指令2条,由5个小组组成一个大组,浮点计算需要用的操作数全部提前2个大组通过1 位访存指令和低高位合并指令放到指定寄存器中;在核心计算代码的最开头,对结果矩阵和第二个源矩阵子块进行预取,其中结果矩阵的预取地址设为两倍的运算数据集大小减去运算数据单元大小,第二个源矩阵子块的预取地址设为运算数据集大小,预取指令的频率等于高速缓冲存储器行的大小除以计算数据集的大小。
2.如权利要求1所述基于龙芯3A的单精度矩阵乘法优化方法,特征在于所述数据分块并拷贝步骤采取将龙芯3A的两个单精度源矩阵数据分别以龙芯3A —级缓存容量的1/4 为间隔拷贝到目标地址空间中,使两个子块的拷贝目标地址所对应的一级缓存地址不在同一组。
全文摘要
本发明公开了一种基于龙芯3A的单精度矩阵乘法优化方法,特征是先将龙芯3A的两个单精度源矩阵按分别不大于一级缓存一半和不大于二级缓存一半的原则划分为两个子矩阵;在龙芯3A的32位访存指令、单精度浮点乘加指令和预取指令的矩阵乘法核心计算代码中采用龙芯3A的128位访存指令和并行单精度浮点指令,并采用两倍的运算数据集大小减去运算数据单元大小预取地址计算方式来对数据进行预取,从而使浮点运算部件基本上能够满负荷运转;克服了地址非对齐数据预取无效的问题,使地址非对齐的单精度矩阵乘法执行效率接近地址对齐的单精度矩阵乘法;运算速度比基础线性代数子程序库(GotoBLAS)版本2-1.07平均提高了90%以上。
文档编号G06F17/16GK102214160SQ20111019113
公开日2011年10月12日 申请日期2011年7月8日 优先权日2011年7月8日
发明者何颂颂, 张斌, 许耿纯, 顾乃杰 申请人:中国科学技术大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1