一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种基于ARM架构的计算优化方法、系统及装置

2022-07-31 03:19:33 来源:中国专利 TAG:

一种基于arm架构的计算优化方法、系统及装置
技术领域
1.本发明涉及科学计算技术领域,尤其涉及一种基于arm架构的计算优化方法、系统及装置。


背景技术:

2.octave是一种科学计算软件,提供与matlab语法兼容的开放源代码的科学计算及数值分析工具,旨在解决线性和非线性的数值计算问题,内置功能强大的数学函数及可扩充的库,但它本身性能还不是很好,而且只支持单线程,由于数据量的增加,程序的复杂度也在不断提高,因此需要使用大量的cpu来处理这些问题,而对于这些问题,octave自身目前是无法满足需求的。
3.对于octave加速依赖的环境,arm作为目前市场上占有率较高的重要架构之一,相较于x86架构的cisc(复杂指令集),它提供了一套risc(精简指令集),避免复杂指令,并且有着高性能,低功耗的优势,但octave软件在arm架构下处理器上运行得效果并不怎么理想,而在x86环境下对octave的优化很难直接移植到arm环境下,因此需要在arm架构下进一步改进。


技术实现要素:

4.有鉴于现有技术的上述缺陷,本发明所要解决的技术问题是提供一种基于arm架构的计算优化方法、系统及装置,具体结合armv8体系结构,用以提升octave软件在arm平台上的数值计算问题的性能。
5.为实现上述目的,本发明提供了一种基于arm架构的计算优化方法,包括以下步骤:
6.s1:获取octave源代码,配置octave相关arm环境;
7.s2:对octave中的算子进行优化;
8.s3:对octave中待优化的函数进行循环判断,函数内部是否包含循环代码,如果包含循环代码,进入步骤四,如果不包含循环代码,则进入步骤五;
9.s4:对函数内部循环进行优化;
10.s5:对函数进行函数本身优化;
11.s6:对改写好的octave源代码进行编译优化。
12.进一步的,所述s2步骤中,所述octave中的一些基本算子包括但不限于加减乘除对数据元素进行逐个运算的操作;算子优化为根据处理的数据分布按照块划分或者等差数列规律划分进行处理。
13.进一步的,所述s3步骤中,对octave中待优化的函数进行循环判断,包括判断是否包括while循环、for循环和do-while循环。
14.进一步的,所述s4步骤中,对函数体内部循环进行优化包括对函数体内部循环本身的优化和用openmp进行多核处理的并行优化。
15.进一步的,所述对函数体内部循环本身的优化,包括根据循环本身计算复杂性大小进行合并、拆分和改造,其中:对于循环本身一次复杂计算超过5次作为判断,对于复杂计算超过5次的,称之为大循环,对大循环进行拆分操作,其中复杂计算是包含乘除复合操作的计算;对于复杂计算小于等于5次的,称之为小循环,对函数内多个小循环进行合并操作;对于while循环、do-while循环,改造成for循环。
16.进一步的,对于复杂计算超过5次的循环,将循环体中前5次拆分到一个循环中,并以此作为后面拆分的循环的输入,实现循环的拆分操作;对于复杂计算小于等于5次的循环,把函数内几个小循环,在循环次数相同的情况下,可以一起合成一个循环,实现循环的合并操作。
17.进一步的,所述用openmp进行多核处理的并行优化包括对函数体内部循环的循环展开、openmp并行处理、并行任务的合理划分。
18.进一步的,所述对函数体内部循环的循环体展开包括对循环内容进行改写,使得在一次循环内完成之前一次或者两次的操作;
19.所述对函数体内部循环的openmp并行处理,在要并行处理的操作语句前添加openmp的调用指令,使这些操作可以分发到不同的核心上进行计算;
20.所述对函数体内部循环的并行任务的合理划分,对不同计算核心上任务进行均匀划分,然后进行测试,选出不同粒度划分下,最短的运行时间的任务大小划分,作为最小任务划分规模。
21.进一步的,所述s5步骤中,对函数本身进行函数优化,包括传参优化跟内联小函数优化。
22.进一步的,所述s6步骤中,对改写好的octave源代码进行编译优化包括向量化优化、流水线优化和编译选项优化。
23.进一步的,所述s6步骤中,所述对改进的octave源代码进行向量化优化时,在arm架构中,编译器采用neon对程序进行编译优化;对改进的octave源代码进行流水线优化时,在arm架构下,需要多指令支持多发射乱序执行;对改进的octave源代码进行编译选项优化时,选择o2选项优化,不会进行小函数内联和循环打开。
24.本发明还提供一种基于arm架构的计算优化系统,包括:
25.源代码获取模块,用于获取octave源代码,配置octave相关arm环境;
26.算子优化模块,用于对octave中的算子进行优化;
27.循环判断模块,用于对octave中待优化的函数进行循环判断,函数内部是否包含循环代码,如果包含循环代码,则通过内部循环优化模块对函数内部循环进行优化,如果不包含循环代码,则通过函数本身优化模块对函数进行函数本身优化;
28.内部循环优化模块,用于对函数内部循环进行优化;
29.函数本身优化模块,用于对函数进行函数本身优化;
30.编译优化模块,用于对改写好的octave源代码进行编译优化。
31.本发明的有益效果是:
32.本发明可以解决octave软件在arm平台上性能不好的问题,由于我们对基本算子跟很多函数都进行了一定程度上的优化,并且使原来只能单核运行的程序,现在能够自动的在多cpu上运行,故很大程度上提高了依赖octave执行的程序的运行效率。我们将本发明
程序进行封装,可以作为一个新的octave软件版本进行发布,以供科学计算领域,特别是数学计算领域的科学家或者工程师们使用。
33.以下将结合附图对本发明的构思、具体结构及产生的技术效果作进一步说明,以充分地了解本发明的目的、特征和效果。
附图说明
34.图1是实施例1的基于arm架构的octave计算加速优化方法的流程图;
35.图2是实施例1的基于arm架构的octave计算加速优化方法的流程图;
36.图3是实施例2的算子优化图;
37.图4是实施例2的向量化加速示意图;
38.图5是实施例2的流水线加速示意图。
具体实施方式
39.实施例1
40.本实施例提出一种基于arm架构的octave计算加速优化方法,如图1、图2所示,为本实施例的基于arm架构的octave计算加速方法流程图。
41.本实施例提出的基于arm架构的octave计算加速方法中,包括以下步骤:
42.s1:获取octave源代码,配置octave相关arm环境;
43.s2:对octave中的算子进行优化;
44.本实施例中,一些基本算子包括加减乘除等一系列对数据元素进行逐个运算的操作。算子优化主要是根据处理的数据分布按照块划分或者等差数列规律划分进行处理。
45.s3:对octave中待优化的函数进行循环判断,函数内部是否包含循环代码,如果包含循环代码,进入步骤四,如果不包含循环代码,则进入步骤五;
46.本实施例中,对octave中待优化的函数进行循环判断,函数内部是否包含循环代码,主要判断是否包括while循环、for循环和do-while循环。
47.s4:对函数内部循环进行优化;
48.本实施例中,对函数体内部循环的优化主要包括循环体展开等一系列循环本身的优化和用openmp进行多核处理的并行优化两部分。
49.其中,对于循环本身的优化,主要是根据循环本身计算复杂性大小进行合并、拆分和改造。
50.本实施例中,对于循环本身一次复杂计算超过5次作为判断,对于复杂计算超过5次的,称之为大循环,对于复杂计算小于等于5次的,称之为小循环,对于复杂计算过多的循环,可以进行拆分操作,来更好的利用寄存器,对于复杂计算不多的循环,可以将函数内多个小循环进行合并操作,来减少对循环变量的操作。
51.进一步的,对复杂计算超过5次的循环进行拆分,可以把前5次的复杂计算放到一个循环里面,之后的复杂计算放到另一个的循环里面,实现循环的拆分;
52.对复杂计算不超过5次的循环进行合并,根据函数内,相邻的几个小循环,在循环次数相同的情况下,可以合并到一个循环里面,减少对循环变量的操作。
53.在本实施例中,对于while循环,do-while循环,要改造成for循环,方便后续优化。
54.在本实施例中,在arm架构下,一个计算节点会包含多个核心,对函数体内部的循环利用openmp进行多核处理的并行优化循环,主要包括循环展开,openmp并行处理,并行任务的合理划分。
55.对函数体内部循环的循环展开,主要对循环内容进行改写,使得在一次循环内完成之前一次或者两次的操作,增加并行性;
56.对函数体内部循环的openmp并行处理,在要并行处理的操作语句前添加openmp的调用指令,使这些操作可以分发到不同的核心上进行计算,以此利用arm的多核心优势,使计算效率进一步提高;
57.对函数体内部循环的并行任务的合理划分,对不同计算核心上任务进行均匀划分,然后进行测试,选出不同粒度划分下,最短的运行时间的任务大小划分,作为最小任务划分规模。
58.s5:对函数进行函数本身优化;
59.本实施例中,对函数本身进行函数优化,主要包括传参优化跟内联小函数优化。
60.s6:对改写好的octave源代码进行编译优化。
61.本实施例中,对改进的octave源代码进行编译器优化主要包括向量化优化、流水线优化,和编译选项优化。
62.进一步的,对改进的octave源代码进行向量化优化时,在arm架构中,编译器采用neon对程序进行编译优化;
63.对改进的octave源代码进行流水线优化时,在arm架构下,需要多指令支持多发射乱序执行。
64.对改进的octave源代码进行编译选项优化时,选择o2选项优化,不会进行小函数内联和循环打开。
65.实施例2
66.本实施例应用于实施例1提出一种基于arm架构的octave计算加速优化方法,提出了一种具体的实施方式。
67.s1、获取octave软件源代码并检查和配置octave相关arm环境。
68.首先获取octave源代码,获取的是octave6.4版本代码,然后检查相应arm环境:具体的为arm架构的华为鲲鹏920处理器,在armv8架构下的体系结构包含内存,三级缓存,包含通用寄存器跟128bit的向量寄存器,l1cache大小是64kb,l2cache大小是512kb,l3cache大小是1mb,是一个simd系统,配置好octave运行环境。
69.s2、对octave软件中的一些基本算子进行优化。
70.本实施例中,一些基本算子包括对矩阵的加,减,点乘,点除等一系列对各个元素进行逐一操作的运算。
71.对这些操作进行优化,选择按块划分的方式进行优化。比如对两个1x100大小的矩阵进行加法操作,在原有运算下,需要从1到100每个对应位置的两个数逐个相加,按块划分之后,如图3算子优化图中的a,把每个矩阵划分成1到25,26到50,51到75,76到100共四个部分,然后用四个线程分别在四个cpu上去同时运行,理论上可以达到快四倍的效果。用户之前正常的串行代码,在使用优化过的算子后,原来只能单个cpu上运行得程序,现在可以自动的在多个cpu上运行,极大地提高了程序运行效率。
72.当数据分布不均匀的时候,比如同样的两个1x100大小的矩阵相加,但数据分布为前面都是小数,后面逐渐都变成了大数,因为对一个小数的计算和一个大数的计算耗时是不一样的,如果还是按照块划分的方式进行优化,就会导致每个cpu计算时间不一样,总的计算时间变长的问题。可以按照等差序列的划分方式进行优化,如图3中的b,我们同样的采用四个线程,使数据均匀的划分到每个cpu上运行,比如1

26

51

76

97在cpu1上运行等,这样每个cpu运行时间差不多,但要比按照图3中a的划分方式,总的运行时间更短。
73.s3、对octave中待优化的函数进行循环判断。
74.在本实施例中,对于待优化的函数,主要判断是否包含循环体,主要包括while循环、for循环和do-while循环,在函数体内主要对这些循环进行优化。如果包含循环,则进入s4步骤中,否则直接进入s5步骤中。
75.s4、对函数内部循环进行优化。
76.在本实施例中,在一个函数内部,如果存在多个相邻的小循环,即复杂计算不超过5次的循环,且循环次数一样,以一个100个元素大小的数组a,使每个元素加1为例,即a[i]加1,使i从0到99循环100次,同样的一个100的元素大小的数组b,使每个元素都乘以2,即b[j]乘以2,使j从0到99循环100次,这样的两个循环就可以合并到一起变成一个循环,使得每次循环同时计算a元素加1,b元素乘以2的操作,以此减少对循环变量的操作,而且有利于增加处理器乱序执行的机会,提升指令级的并行能力。
[0077]
对于函数内存在复杂计算超过5次的大循环,即循环体内执行的语句过多,就可以把语句拆分到多个循环体内去处理,这里的循环体内语句多少的判断,主要取决于系统寄存器大小,可以将前5次复杂计算放到一个循环内,后面的复杂计算放到另一个循环内,有利于提升寄存器的利用效率。
[0078]
在本实施例中,对while循环和do-while循环进行改写,使得成为for循环,一般情况下,while循环都可以改成for循环,然后就可以进行后续优化。
[0079]
对所有的for循环进行循环展开优化,降低循环带来的开销,加快程序执行速度的方法。以一个100个元素大小的数组a,使每个元素加1为例,要循环100次,我们循环展开2次,每次循环使相邻两个数都加1,这样使循环增量从之前得1变为2,使得循环次数减少到50次,减少对循环变量的操作,从而降低了循环带来的开销,增加了性能。
[0080]
在以上优化的基本上,使用openmp,把原来的单cpu程序,在用户透明的情况下,变成多cpu运行程序。具体的做法就是,在要并行的for循环体前面加上openmp的编译指导语句“#pragma omp parallel for”,使得程序能够自动的在多核上运行。具体的作用就是告诉编译器,将循环拆分为多个线程,分别在不同的核上同时运行,具体线程个数将根据系统的cpu个数和任务大小而定。一般情况下,可以通过实验测试每个核的最小任务大小,从而合理划分任务大小,得到最佳运行线程数。这样可以充分利用arm的多核心优势,进一步增加octave程序性能。
[0081]
s5、对函数本身进行函数优化。
[0082]
在本实施例中,在函数需要传递参数时,函数参数优先通过寄存器传递,比较大时通过栈传递。对于参数是大结构体,或者类时,会有调用时的复制开销和返回时的销毁开销。将参数改为指针传递,这样在函数传递参数时,只需要传递一个指针即可。指针可以通过寄存器传递,免去了较大参数调用时的复制开销和返回时的销毁开销,节约了时间。
[0083]
在本实施例中,在函数体内调用其他函数时,函数之间会来回调用,增加开销,对于调用的函数是小函数,函数体内只有几条简单的语句,在函数体内将调用的函数作内联处理,编译器可以自动的将小函数的函数体替换到函数调用处,减少了函数之间调用切换的开销。
[0084]
s6、对改写好的octave源代码进行编译优化。
[0085]
在本实施例中,经过上述一系列优化之后,还可以对代码进行编译优化,如图4所示,计算c=a b;普通的计算方式就是用64bit寄存器先计算a1加b1,把结果存入c1,依次算出c2,c3,c4一共要计算四次,而在armv8架构下的体系结构里包含有128bit向量寄存器,根据arm的neon指令,向量化后,一次可以同时计算c1和c2,总共只需要两次计算,即可计算完成,时间缩短一半。
[0086]
对代码进行编译优化,还可以选择流水线方式进行优化,具体的在编译选项中添加-mtune=tsv110指令,如图5所示,对一个矩阵的每个元素进行加1操作,对每个元素的操作分为三个步骤,分别为取值,加1,存储,假设每个操作时间都相等,在流水线处理之前,第一个元素经过取值,加1,存储操作之后才能进行第二个元素的操作。对矩阵的四个元素全部完成操作需要花费12t的时间,而经过流水线处理之后,在对第一个元素经过取值会后,在进行加1操作的时候,就同时可以对第二个元素进行取值操作,同样的,当第一个元素存储的时候,第二个元素可以进行加1操作,第三个元素可以进行取值操作,总的运行时间更少,在进行流水线化之后,程序的运行时间也可以很大程度上的缩短,进而提高octave软件运行效率。
[0087]
最后gcc为了满足用户不同程度优化的需要,默认提供了4种级别的优化选项用来对编译时间、目标文件长度和执行效率这个三维模型进行了取舍和平衡;其中-o0为默认选项,不提供任何优化;-o1为部分编译优化,可以减少生产代码的尺寸;-o2是在o1的基础上进一步的优化,但不提供循环展开和函数内联;-o3是最高级别的优化,会引入编译器的自动向量化,但可能产生一些问题,特别的对于调试程序会带来一定程度的困难。由于前面已经对octave函数进行专门的循环展开和函数内联,并且向量化程序,所以我们选择-o2编译选项,能够使我们的octave程序优化的更加合理。
[0088]
以上详细描述了本发明的较佳具体实施例。应当理解,本领域的普通技术人员无需创造性劳动就可以根据本发明的构思做出诸多修改和变化。因此,凡本技术领域中技术人员依本发明的构思在现有技术的基础上通过逻辑分析、推理或者有限的实验可以得到的技术方案,皆应在由权利要求书所确定的保护范围内。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献