发明内容
有鉴于此,本发明实施例旨在在链式执行中涉及仅故障优先矢量加载指令时,提高其后续矢量指令的运行效率。
为了达到这个目的,根据本公开的一方面,提供了一种指令发射单元,包括:
指令拆分器,用于将待执行矢量指令拆分成微指令;
微指令索引获取器,用于基于所述拆分后的微指令所涉及的元素范围,获取所述微指令的有效元素个数索引;
索引比较子单元,用于将获取的有效元素个数索引与第一索引比较,所述第一索引是尚未处理完的仅故障优先微指令的有效元素个数索引;
微指令发射控制器,用于在所述有效元素个数索引小于第一索引的情况下,将拆分后的微指令发送到矢量执行单元执行。
可选地,该指令发射单元还包括:操作数相关性判断子单元,用于确定第一微指令是否执行完毕,其中,所述拆分后的微指令中的操作数依赖于所述第一微指令;其中,所述微指令发射控制器在第一微指令已经执行完毕、且所述有效元素个数索引小于第一索引的情况下,才将拆分后的微指令发送到矢量执行单元执行。
可选地,所述微指令索引获取器按照如下公式基于所述拆分后的微指令所涉及的元素范围,获取所述微指令的有效元素个数索引:
vl_index(i)=8*(i+1)/VREG_NUM–1,
其中,vl_index(i)为所述有效元素个数索引,VREG_NUM是所述待执行矢量指令要回写的矢量寄存器个数,i是所述元素范围的序号,i=0,1,2,…..,VLEN*VREG_NUM/DPLEN-1,其中,VLEN是矢量寄存器位宽,DPLEN是矢量执行单元的处理位宽。
可选地,如果VREG_NUM=8,序号最低的所述元素范围对应的有效元素个数索引为0000,元素范围每高一个序号,所述有效元素个数索引增加0001。
可选地,如果VREG_NUM=4,序号最低的所述元素范围对应的有效元素个数索引为0001,元素范围每高一个序号,所述有效元素个数索引增加0010。
可选地,如果VREG_NUM=2,序号最低的所述元素范围对应的有效元素个数索引为0011,元素范围每高一个序号,所述有效元素个数索引增加0100。
可选地,如果VREG_NUM=1,序号最低的所述元素范围对应的有效元素个数索引为0111,元素范围每高一个序号,所述有效元素个数索引增加1000。
可选地,所述指令拆分器将待执行矢量指令拆分成(VLEN·LMUL)/DPLEN条微指令,其中,VLEN为矢量寄存器位宽,LMUL为待执行矢量指令中矢量占用的矢量寄存器数目,DPLEN为矢量执行单元的处理位宽。
可选地,所述操作数相关性判断子单元按照以下方式确定第一微指令是否执行完毕:
获取拆分后的微指令中的操作数;
获取之前拆分出的微指令中产生所述操作数的微指令;
确定获取的微指令是否执行完毕。
可选地,所述微指令发射控制器在第一微指令未执行完毕、或者所述有效元素个数索引小于第一索引的情况下,保持所述拆分后的微指令。
可选地,所述矢量执行单元包括多个矢量运算子单元,所述微指令发射控制器将所述拆分后的微指令并行发送到所述多个矢量运算子单元执行。
根据本公开的一方面,还提供了一种矢量执行单元,包括:
矢量运算子单元,用于执行待执行矢量指令拆分后的微指令;
第一索引记录器,用于记录第一索引,并响应于指令发射单元的请求,发射所述第一索引,其中,所述第一索引是所述矢量运算子单元尚未处理完的仅故障优先微指令的有效元素个数索引
根据本公开的一方面,还提供了一种处理单元,包括:
取指令单元,用于获取待执行矢量指令;
指令译码单元,用于对所述待执行矢量指令进行译码;
如上所述的指令发射单元;
如上所述的矢量执行单元。
根据本公开的一方面,还提供了一种计算设备,包括:
如上所述的处理单元;
存储器,与所述处理单元耦接,存储所述待执行矢量指令。
根据本公开的一方面,还提供了一种数据中心,包括如上所述的计算设备。
根据本公开的一方面,还提供了一种矢量执行加速方法,包括:
将待执行矢量指令拆分成微指令;
基于所述拆分后的微指令所涉及的元素范围,获取所述微指令的有效元素个数索引;
将获取的有效元素个数索引与第一索引比较,所述第一索引是尚未处理完的仅故障优先微指令的有效元素个数索引;
在所述有效元素个数索引小于第一索引的情况下,将拆分后的微指令发送到矢量执行单元执行。
可选地,在将拆分后的微指令发送到矢量执行单元执行之前,所述方法还包括:确定第一微指令是否执行完毕,其中,所述拆分后的微指令中的操作数依赖于所述第一微指令;所述在所述有效元素个数索引小于第一索引的情况下,将拆分后的微指令发送到矢量执行单元执行,包括:在第一微指令已经执行完毕、且所述有效元素个数索引小于第一索引的情况下,才将拆分后的微指令发送到矢量执行单元执行。
可选地,所述基于所述拆分后的微指令所涉及的元素范围,获取所述微指令的有效元素个数索引,包括按照以下公式计算所述有效元素个数索引:
vl_index(i)=8*(i+1)/VREG_NUM–1,
其中,vl_index(i)为所述有效元素个数索引,VREG_NUM是所述待执行矢量指令要回写的矢量寄存器个数,i是所述元素范围的序号,i=0,1,2,…..,VLEN*VREG_NUM/DPLEN-1,其中,VLEN是矢量寄存器位宽,DPLEN是矢量执行单元的处理位宽。
可选地,如果VREG_NUM=8,序号最低的所述元素范围对应的有效元素个数索引为0000,元素范围每高一个序号,所述有效元素个数索引增加0001。
可选地,如果VREG_NUM=4,序号最低的所述元素范围对应的有效元素个数索引为0001,元素范围每高一个序号,所述有效元素个数索引增加0010。
可选地,如果VREG_NUM=2,序号最低的所述元素范围对应的有效元素个数索引为0011,元素范围每高一个序号,所述有效元素个数索引增加0100。
可选地,如果VREG_NUM=1,序号最低的所述元素范围对应的有效元素个数索引为0111,元素范围每高一个序号,所述有效元素个数索引增加1000。
可选地,所述确定第一微指令是否执行完毕,包括:
获取拆分后的微指令中的操作数;
获取之前拆分出的微指令中产生所述操作数的微指令;
确定获取的微指令是否执行完毕。
可选地,在确定第一微指令是否执行完毕之后,所述方法还包括:在第一微指令未执行完毕、或者所述有效元素个数索引小于第一索引的情况下,保持所述拆分后的微指令。
本公开实施例巧妙地运用有效元素个数索引的编码和比较,低成本地完成了链式执行中一条矢量指令需要参考的有效元素个数索引是否已准备好的判断。本公开实施例基于所述拆分后的微指令所涉及的元素范围,获取所述微指令的有效元素个数索引,并将获取的有效元素个数索引与第一索引比较,所述第一索引是尚未处理完的仅故障优先微指令的有效元素个数索引。若所述有效元素个数索引小于第一索引,说明该待执行矢量指令需要参考的有效元素个数索引已准备好,这样就不用等待之前的仅故障优先矢量加载指令全执行完并返回有效元素个数的更新值后才开始执行,大大提高了链式执行中仅故障优先矢量加载指令后续矢量指令的运行效率。
具体实施方式
以下基于实施例对本发明进行描述,但是本发明并不仅仅限于这些实施例。在下文对本发明的细节描述中,详尽描述了一些特定的细节部分。对本领域技术人员来说没有这些细节部分的描述也可以完全理解本发明。为了避免混淆本发明的实质,公知的方法、过程、流程没有详细叙述。另外附图不一定是按比例绘制的。
在本文中使用以下术语。
免费开放的精简指令集架构:即Risc-V指令集架构,它是美国计算机圣地伯克利发起的一个项目,是一个免费且开放使用的精简指令集架构。精简指令集与复杂指令集不同。统治个人计算机的x86就是属于复杂指令集类的接口规范。精简指令集对复杂指令集中的一些不常用的指令做了精简。统治嵌入式和手机领域的接口规范就是精简指令集类的接口规范。当然,免费开放的精简指令集架构也是精简指令集类的接口规范,其最大优势就是开放和免费,被称为硬件领域的Linux,项目由社区共同维护,使用该架构不需要收取费用,也没有任何硬性的使用限制。目前,很多大公司都加入了该架构的基金会,来摆脱行业巨头的控制。该架构有后发优势,ARM和X-86都发展了很多年,大规模的商用需要考虑向前兼容,而免费开放的精简指令集架构没有历史包袱,所以指令集非常的精简,性能表现也非常优秀。
免费开放的精简指令集架构的矢量扩展指令集:由于信息社会中,经常需要作大量同种类型的运算,例如对互联网上的大量用户的若干项数据进行同样的处理运算,需要大量的单一指令进行处理,为了避免这种单一指令处理带来的开销,产生了矢量运算指令。将单一运算中涉及的数据项看作矢量中的一个元素,通过这种矢量运算的方式一次产生批量单一数据的运算结果。基于这种构想,对免费开放的精简指令集架构扩展出了若干针对矢量运算的指令,成为免费开放的精简指令集架构的矢量扩展指令集。下文中的术语有效元素个数EN/SEW/LMUL/仅故障优先/有效元素个数等参数都来自于该指令集。
矢量寄存器位宽(VLEN):矢量寄存器容纳的比特位数。矢量寄存器是处理器中矢量执行单元执行矢量运算时存储矢量运算中的矢量的寄存器。VLEN是免费开放的精简指令集架构的矢量扩展指令集中所定义的硬件配置参数,免费开放的精简指令集架构的矢量扩展指令集定义了32个矢量寄存器VR0~VR31,如图4所示,其中每个寄存器的比特位数用VLEN表示,必须为2的次方,例如64,128,256,512,1024等。
矢量标准元素位宽(SEW):矢量中的元素201占用矢量寄存器的位数。矢量是由元素201组成的,矢量存储在一个或多个矢量寄存器中。对于一个矢量寄存器来说,其一般不止存储一个元素201。每个元素201占用的位数即SEW。SEW是免费开放的精简指令集架构的矢量扩展指令集中所定义的软件可配置参数,可以支持宽度为8,16,32,64等。图5示出SEW=8和SEW=16的配置方式。在SEW=8时,每个元素201占据8位。如果VLEN=128,矢量寄存器就能够容纳128/8=16个元素201。在SEW=16时,每个元素201占据16位。如果VLEN=128,矢量寄存器就能够容纳128/16=8个元素201。
矢量占用的矢量寄存器数目(LMUL),又称矢量寄存器组,是存储矢量中的所有元素需要的矢量寄存器数目。矢量是由元素组成的,但每个矢量寄存器容纳的元素数目有限,因此可能需要多个矢量寄存器才能表达出一个矢量,表达一个矢量需要的矢量寄存器数目即LMUL。LMUL是免费开放的精简指令集架构的矢量扩展指令集中所定义的软件可配置参数。图6中示出LMUL分别为1、2、4的情况。每个矢量寄存器可以容纳4个元素。当矢量包括4个元素时,LMUL=1,即1个矢量寄存器就能表达出该矢量。当矢量包括8个元素时,LMUL=2,即2个矢量寄存器才能表达出该矢量。当矢量包括16个元素时,LMUL=4,即4个矢量寄存器才能表达出该矢量。
有效元素个数:有效元素个数,它是免费开放的精简指令集架构的矢量扩展指令集中的一个控制寄存器参数,用来指示一条矢量指令需要处理和更新的有效元素个数。一条矢量指令未必会处理和占用整个控制寄存器的所有元素,占用的元素叫做有效元素,空闲不占用的元素叫做无效元素。如图7A所示,当有效元素个数=11时,矢量指令可能只处理元素0-10这11个元素,对于元素12-15不处理,元素12-15空闲。如图7B所示,当有效元素个数=16时,矢量指令可能处理矢量寄存器中的所有元素0-15。这个参数具有重要意义,后续矢量指令都需要参考该参数进行矢量运算和回写。一般来说,矢量指令执行时,一方面可能需要之前的矢量指令执行的结果,另一方面要参考有效元素个数来确认有效元素个数进行运算和回写。有效元素个数只能被vsetvli/vsetvl这两条写控制寄存器的指令以及仅故障优先矢量加载指令改写。仅故障优先矢量加载指令将在下面详述。
vsetvli/vsetvl:免费开放的精简指令集架构的矢量扩展指令集中用来设置SEW/LMUL/有效元素个数参数的指令。例如,在VLEN=128的情况下,设置LMUL=4,SEW=32,有效元素个数=11,则VR0~VR3组成的VLEN*LMUL=128*4=512位矢量寄存器组可以看作能够容纳VLEN*LMUL/SEW=16个元素,从低到高分别为元素0到元素15,每个元素的位宽为16位。但是,这16个元素的位置未必都被用来放置元素。有效的元素(即放置元素的元素位置)由有效元素个数指定。由于有效元素个数=11,最低的11个元素,即元素0~元素10,为有效元素,即最低的11个元素位置放置元素,其余元素位置空闲。
矢量加载指令:将矢量存储在矢量寄存器中的指令。在存储时,矢量的每个元素占用一个SEW位置,整个矢量占用LMUL个矢量寄存器,这LMUL个矢量寄存器中最低的有效元素个数位的位置放置元素,其余位置不放置元素。
仅故障优先矢量加载指令:这类指令与普通矢量加载指令的区别是普通加载指令在加载任何有效元素时发生访问错误时,都会响应异常,而仅故障优先矢量加载指令只有在加载第0个元素(最低元素)发生访问错误时,才会响应异常,而若非第0个元素发生访问错误时,只会将有效元素个数更新为已处理的无访问错误的总元素个数。如图8所示,加载一个11个元素的矢量时,本来该矢量应该占用元素0-10的位置。当从低位到高位加载的过程中,加载元素0~3时无访问错误,而加载元素4时发生访问错误,则将有效元素个数更新为4,表示有效元素为0~3。仅故障优先矢量加载指令也是免费开放的精简指令集架构的矢量扩展指令集中除了setvl/setvli以外唯一可以修改有效元素个数的指令。
链式执行(chaining):一种矢量执行的加速机制。它在后面的矢量指令需要以前面的矢量指令写入矢量寄存器的结果作为操作数进行运算的情况下,不是等待前面的矢量指令整个执行完成后再执行,而是将指令分成多个微指令,将已执行完的微指令的执行结果提前输出给后面的指令,这样,后面的指令如果得到前面的指令的一部分微指令的结果可以运行,则不需要等待整个前面的指令的执行结果,减小了等待时间,提高了矢量运算效率。例如,矢量指令A产生结果写入一个矢量寄存器VRX,而矢量指令B需要以矢量寄存器VRX的值作为操作数进行运算,则在正常情况下,矢量指令B需要等待矢量指令A完成后,才可以拿到VRX的结果作为操作数进行运算,即指令B的执行依赖于指令A的结果,指令B和指令A之间存在相关性。由于矢量由元素组成,矢量运算以元素为单位,矢量运算的结果VRX也包含多个元素,在元素个数较多,而运算单元的执行能力有限时,每次只可以处理并产生一部分元素的运算结果,这部分结果可以提前输出给矢量指令B所在的运算单元进行处理。如果这部分元素的运算结果对于矢量指令B分成的某些运算足够,可以减少矢量指令B的等待时间,从而加速矢量运算的整体执行效率。
矢量执行单元的处理位宽(DPLEN):如上所述,在矢量的元素个数较多,而矢量执行单元的执行能力有限时,对于指令涉及的矢量,每次只可以处理并产生该矢量一部分元素的运算结果,这部分元素的位数即DPLEN。
微指令:如上所述,由于矢量执行单元每次只能执行DPLEN位的元素运算,将指令中用于该DPLEN位的元素运算的部分划分出来,作为一个微指令。
操作数:操作数是指令中的运算符作用的实体,它规定了指令中进行运算的量。例如,矢量乘法指令vmul.vv vr4,vr0,vr3表示将矢量vr4、矢量vr0、矢量vr3相乘,得到的矢量作为新的矢量vr4,这里,矢量vr4、矢量vr0、矢量vr3都是该矢量乘法指令需要的操作数。
有效元素个数索引:有效元素个数索引不是有效元素个数,它是为了有效元素个数的比较给微指令涉及的元素范围编制的索引。对于普通矢量指令来说,该索引反映了其分成的微指令涉及的元素范围对应于矢量寄存器的哪段区间。对于仅故障优先矢量加载指令来说,它反映了仅故障优先矢量加载指令分成的微指令涉及的元素范围对应于矢量寄存器的哪段区间。如图13所示,指令A是一条仅故障优先矢量加载指令。指令B是跟随其后的一条普通指令。对于指令A来说,DPLEN为4个元素的位宽。假设指令A当前拆分出的微指令为微指令A-2,按照上文的规则,其有效元素个数索引编码为0101。已经发射执行的微指令为微指令A-0和微指令A-1。指令B分出的微指令B-0以及微指令B-1由于作用于元素0-3的元素范围,按照上文的规则,其有效元素个数索引编码为0001,由于编码后的有效元素个数索引0001不小于未执行完的A-0的索引0001,因此需要等待A-0执行完毕确认有效元素个数更新信息即可发射。对于指令B拆分出的微指令B-2以及B-3,按照上文的规则,其有效元素个数索引编码为0011。由于0011不小于A-0和A-1……的索引0001和0011,因此需要等待A-0和A-1均执行完毕确认有效元素个数更新信息即可发射。指令B拆分出的微指令B-4以及B-5的有效元素个数索引为0101。由于其不小于A-0、A-1以及A-2的索引0001、0011、0101,因此即便A-0和A-1在矢量运算子单元1213均已执行完毕,也不能超越微指令A-2提前执行和发射,需要等待A-2也发射并执行完毕。
数据中心
数据中心是全球协作的特定设备网络,用来在互联网网络基础设施上传递、加速、展示、计算、存储数据信息。在今后的发展中,数据中心也将会成为企业竞争的资产。由于数据中心每时每刻要对大量数据进行运算,矢量运算应运而生。矢量运算可以将需要进行同种运算的大量离散数据矢量化,用离散数据构成矢量,通过对矢量进行运算,而不是对单个元素进行计算,达到了提高需要进行同种运算的数据运算效率的作用。
在传统的大型数据中心,网络结构通常如图1所示,即互连网络模型(hierarchical inter-networking model)。这个模型包含了以下部分:
服务器10:各服务器10是数据中心的处理和存储实体,数据中心中大量数据的处理和存储都是由这些服务器10完成的。
接入交换机3:接入交换机3是用来让服务器10接入到数据中心中的交换机。一台接入交换机3接入多台服务器10。接入交换机3通常位于机架顶部,所以它们也被称为机顶(Top of Rack)交换机,它们物理连接服务器。
汇聚交换机2:每台汇聚交换机2连接多台接入交换机3,同时提供其他的服务,例如防火墙,入侵检测,网络分析等。
核心交换机1:核心交换机1为进出数据中心的包提供高速的转发,为汇聚交换机2提供连接性。整个数据中心的网络分为L3层路由网络和L2层路由网络,核心交换机1为通常为整个数据中心的网络提供一个弹性的L3层路由网络。
通常情况下,汇聚交换机2是L2和L3层路由网络的分界点,汇聚交换机2以下的是L2网络,以上是L3网络。每组汇聚交换机管理一个传送点(POD,Point Of Delivery),每个POD内都是独立的VLAN网络。服务器在POD内迁移不必修改IP地址和默认网关,因为一个POD对应一个L2广播域。
汇聚交换机2和接入交换机3之间通常使用生成树协议(STP,Spanning TreeProtocol)。STP使得对于一个VLAN网络只有一个汇聚层交换机120可用,其他的汇聚交换机2在出现故障时才被使用(上图中的虚线)。也就是说,在汇聚交换机2的层面,做不到水平扩展,因为就算加入多个汇聚交换机2,仍然只有一个在工作。
服务器
图2示出图1中一个服务器10的示意性框图。该服务器10是“中心”系统架构的示例。服务器10可基于目前市场上各种型号的处理器构建,并由WINDOWSTM操作系统版本、UNIX操作系统、Linux操作系统等操作系统驱动。此外,服务器10可以在PC机、台式机、笔记本、服务器和移动通信装置等硬件和/或软件中实施。
如图2所示,本发明实施例的服务器10可以包括一个或多个处理器12,以及存储器14。
服务器10中的存储器14可以主存储器(简称为主存或内存)。用于存储由数据信号表示的指令信息和/或数据信息,例如存放处理器12提供的数据(例如为运算结果),也可以用于实现处理器12与外部存储设备16(或称为辅助存储器或外部存储器)之间的数据交换。
在一些情形下,处理器12可能需要访问存储器14,以获取存储器14中的数据或对存储器14中的数据进行修改。由于存储器14的访问速度较慢,为了缓解处理器12与存储器14之间的速度差距,服务器10还包括与总线11耦合的高速缓冲存储器18,高速缓冲存储器18用于对存储器14中的一些可能会被反复调用的程序数据或者报文数据等数据进行缓存。高速缓冲存储器18例如由静态随机存储器(Static Random Access Memory,简称为SRAM)等类型的存储装置实现。高速缓冲存储器18可以为多级结构,例如具有一级缓存(L1Cache)、二级缓存(L2Cache)和三级缓存(L3 Cache)的三级缓存结构,也可以是三级以上的缓存结构或其他类型缓存结构。在一些实施例中,高速缓冲存储器18的一部分(例如一级缓存,或一级缓存和二级缓存)可以集成在处理器12内部或与处理器12集成于同一片上系统中。
基于此,处理器12可以包括指令执行单元121、以及存储控制单元122等部分。指令执行单元121在执行一些需要修改内存的指令时发起写访问请求,该写访问请求指定了需要写入内存中的写入数据和相应的物理地址;存储控制单元122用于控制是否将写入数据存入写访问请求映射的物理地址指向的存储位置,即当满足某些条件时,允许将写入数据存入写访问请求映射的物理地址指向的存储位置;反之,则不允许将写入数据存入写访问请求映射的物理地址指向的存储位置。
此外,服务器10还可以包括存储设备16、通信设备17。存储设备16例如是通过相应接口与总线11耦合的硬盘、光盘以及闪存等用于信息存取的设备。通信设备17用于通过各种方式与图1的其它服务器和接入交换机3通信。通信设备17例如可以包括一种或多种通信模块,作为示例,通信设备17可以包括适用于特定的无线通信协议的无线通信模块。例如,通信设备17可以包括WLAN模块,用于实现符合电气和电子工程师协会(IEEE)制定的802.11标准的Wi-FiTM通信;通信设备17也可以包括WWAN模块,用于实现符合蜂窝或其他无线广域协议的无线广域通信;通信设备17还可以包括蓝牙模块等采用其它协议的通信模块,或其它自定义类型的通信模块;通信设备17也可以是用于串行传输数据的端口。
当然,不同的服务器10根据主板、操作系统和指令集架构的不同,其结构也可能有所变化。例如目前很多服务器10设置有连接在总线11和各个输入/输出设备之间的输入/输出控制中心,且该输入/输出控制中心可以集成于处理器12之内或独立于处理器12。
处理器
图3是本发明实施例中处理器12的示意性框图。
在一些实施例中,每个处理器12可以包括用于处理指令的一个或多个处理器核120,指令的处理和执行是可以被用户(例如通过应用程序)和/或系统平台控制的。在一些实施例中,每个处理器核120可以用于处理特定的指令集。在一些实施例中,指令集可以支持复杂指令集计算(Complex Instruction Set Computing,CISC)、精简指令集计算(Reduced Instruction Set Computing,RISC)或基于超长指令字(Very LongInstruction Word,VLIW)的计算。不同的处理器核120可以各自处理不同或相同的指令集。在一些实施例中,处理器核120还可以包括其他处理模块,例如数字信号处理器(DigitalSignal Processor,DSP)等。作为一种示例,图3中示出了处理器核1至m,m是非0的自然数。
在一些实施例中,图2示出的高速缓冲存储器18可以被全部或部分集成于处理器12中。且根据不同架构,高速缓冲存储器18可以是位于各个处理器核101之内和/或之外的单个或多级的内部高速高速缓冲存储器(如图3示出的3级高速高速缓冲存储器L1至L3,图3中统一标识为18),也可以包括面向指令的指令高速缓存和面向数据的数据高速缓存。在一些实施例中,处理器12中的各个部件可以共享至少一部分的高速缓冲存储器,如图3所示,处理器核1至m例如共用第三级高速高速缓冲存储器L3。处理器12还可以包括外部高速缓存(未示出),其他高速缓存结构也可以作为处理器12的外部高速缓存。
在一些实施例中,如图3所示,处理器12可以包括寄存器堆126(Register File),寄存器堆126可以包括用于存储不同类型的数据和/或指令的多个寄存器,这些寄存器可以是不同类型的。例如,寄存器堆126可以包括:整数寄存器、矢量寄存器、浮点寄存器、指令寄存器和指针寄存器等。寄存器堆126中的寄存器可以选用通用寄存器来实现,也可以根据处理器12的实际需求采用特定的设计。
处理器12用于执行指令序列(即程序)。处理器12执行每个指令的过程包括:从存放指令的存储器中取出指令、对取出的指令进行译码、执行译码后的指令、保存指令执行结果等步骤,如此循环,直到执行完指令序列中的全部指令或遇到停机指令。
为了实现上述过程,处理器12可以包含取指令单元124、指令译码单元125、指令发射单元130、指令执行单元121和指令引退单元131等。
取指令单元124作为处理器12的启动引擎,用于将指令从存储器14中搬运到指令寄存器(可以是图3示出的寄存器堆26中的一个用于存放指令的寄存器)中,并接收下一个取指地址或根据取指算法计算获得下一个取指地址,取指算法例如包括:根据指令长度递增地址或递减地址。
取出指令后,处理器12进入指令译码阶段,指令译码单元125按照预定的指令格式,对取回的指令进行解码,以获得取回的指令所需的操作数获取信息,从而为指令执行单元121的操作做准备。操作数获取信息例如指向立即数、寄存器或其他能够提供源操作数的软件/硬件。
指令发射单元130通常存在于高性能的处理器12中,位于指令译码单元125与指令执行单元121之间,用于指令的调度和控制,以将各个指令高效地分配至不同的指令执行单元121,使得多个指令的并行操作成为可能。指令经取指、译码并被调度到相应的指令执行单元121之后,相应的指令执行单元121开始执行该指令,即执行该指令所指示的操作、实现相应的功能。本公开实施例主要是在指令发射单元130和执行指令单元121完成的。下面会结合本公开实施例具体描述指令发射单元130和指令执行单元121的具体构造。
指令执行单元121包括矢量执行单元1211、算术运算单元1214、存储指令执行单元1215,分别用于处理不同类型的指令。算术运算单元(ALU)1214是进行整型数运算和逻辑运算的运算单元。矢量执行单元1211是进行矢量运算的运算单元。指令执行单元121在执行某类指令(例如访存指令)时,需要访问存储器14,以获取存储器14中存储的信息或提供需要写入存储器14中的数据。这种执行访存指令的执行单元叫做存储指令执行单元1215。虽然图3中作为示例仅示出以上指令执行单元,本领域技术人员应当理解,还可以根据需要包括任何执行需要执行的功能的指令执行单元。
指令引退单元131主要用于负责将指令执行单元121产生的执行结果写回到相应的存储位置(例如为处理器12内部的寄存器)中,以使后续指令能够从该存储位置处快速获取相应的执行结果。
在处理器12中,各个指令执行单元121可以并行运行并输出相应的执行结果。
访存指令被取指令单元124获取之后,指令译码单元125可以对访存指令进行译码处理,使得访存指令的源操作数可被获取。译码处理后的访存指令被提供至相应的指令执行单元121中,该指令执行单元121可以对访存指令的源操作数进行相应的运算(例如由算术逻辑单元对存储于寄存器中的源操作数进行运算)以获得访存指令对应的地址信息,并根据该地址信息发起相应的请求,例如地址转译请求、写访问请求等。
访存指令的源操作数通常包括地址操作数,存储控制单元122对该地址操作数进行运算以获得访存指令对应的虚拟地址或物理地址。虚拟地址可以转换成物理地址。通过存储控制单元122,可以根据转译后的物理地址访问高速缓冲存储器18和/或存储器14。
根据功能的不同,访存指令可包括加载指令和存储指令。加载指令的执行过程通常不需要对存储器14或高速缓冲存储器18中的信息进行修改,指令执行单元121只需要根据加载指令的地址操作数读取存储于存储器14、高速缓冲存储器18或外部的存储设备中的数据。
不同于加载指令,存储指令的源操作数不仅包括地址操作数,还包括数据信息,存储指令的执行过程通常需要对存储器14和/或高速缓冲存储器18进行修改。存储指令的数据信息可以指向写入数据,该写入数据的来源可以是运算指令、加载指令等指令的执行结果,也可以是处理器12中的寄存器或其他存储单元提供的数据、还可以是立即数。
本公开实施例中指令发射单元130和矢量执行单元1211的详细结构、以及本公开
实施例的实现过程
链式执行是在后面的矢量指令需要以前面的矢量指令写入矢量寄存器的结果作为操作数进行运算的情况下,不是等待前面的矢量指令整个执行完成后再执行,而是将指令分成多个微指令,将已执行完的微指令的执行结果提前输出给后面的指令,这样,后面的指令如果得到前面的指令的一部分微指令的结果可以运行。其相对于等待整个前面的指令的执行结果的方案,提高了矢量运算效率。但是,链式执行对于免费开放的精简指令集架构的矢量扩展指令集中的有效元素个数(有效元素个数)来说,却容易引发问题。
免费开放的精简指令集架构是美国计算机圣地伯克利发起的一个项目,其最大优势就是开放和免费。该架构有后发优势,ARM和X-86都发展了很多年,大规模的商用需要考虑向前兼容,而免费开放的精简指令集架构没有历史包袱,所以指令集非常的精简,性能表现也非常优秀。由于信息社会中,经常需要作大量同种类型的运算,例如对互联网上的大量用户的若干项数据进行同样的处理运算,需要大量的单一指令进行处理,为了避免这种单一指令处理带来的开销,产生了矢量运算指令。将单一运算中涉及的数据项看作矢量中的一个元素,通过这种矢量运算的方式一次产生批量单一数据的运算结果。基于这种构想,对免费开放的精简指令集架构扩展出了若干针对矢量运算的指令,成为免费开放的精简指令集架构的矢量扩展指令集。有效元素个数就来自于免费开放的精简指令集架构的矢量扩展指令集,它是其中的一个控制寄存器参数,用来指示一条矢量指令需要处理和更新的元素个数。一条矢量指令未必会处理和占用整个控制寄存器的所有元素,占用的元素叫做有效元素。一般来说,矢量指令执行时,一方面可能需要之前的矢量指令执行的结果,另一方面要参考有效元素个数进行运算和回写。仅故障优先指令与普通矢量加载指令的区别是普通加载指令在加载任何有效元素时发生访问错误时,都会响应异常,而仅故障优先指令只有在加载第0个元素(最低元素)发生访问错误时,才会响应异常,而若非第0个元素发生访问错误,只会将优先元素个数更新为已处理的无访问错误的总元素个数。仅故障优先指令是免费开放的精简指令集架构的矢量扩展指令集中除了专用于设置有效元素个数的setvl/setvli指令以外唯一可以修改有效元素个数的指令。通常情况下,矢量指令只需要根据setvl/setvli指令来确定有效元素的个数,该参数设置指令执行简单延时较短,不会造成性能瓶颈。但是仅故障优先矢量加载指令作为可能会更改有效元素个数的指令,其执行延时是不确定的,后续的矢量指令必须等待该仅故障优先矢量加载指令返回是否更新有效元素个数才能够正确地执行。这种等待大大降低链式执行的效果。
本公开实施例就是为了应对在链式执行中涉及仅故障优先矢量加载指令时后续矢量指令的运行效率低的问题而产生的,它主要是通过指令发射单元130和矢量执行单元1211实现的。下面详细讨论指令发射单元130的内部结构和本公开实施例的实现过程。
如图3所示,本公开实施例的指令发射单元130包括指令拆分器1301、微指令索引获取器1303、索引比较子单元1304、微指令发射控制器1305。
如上所述,取指令单元124将指令从存储器14中搬运到寄存器堆26中的一个用于存放指令的指令寄存器中。然后,进入指令译码阶段。指令译码单元125按照预定的指令格式,对取回的指令进行译码,以获得取回的指令所需的操作数获取信息,从而为指令执行单元121的操作做准备。如果译码发现该指令是一个矢量运算指令,即待执行矢量指令,将该待执行矢量指令发送到指令发射单元130进行指令向指令执行单元121的发射。
待执行矢量指令进入指令发射单元130后,指令拆分器1301将待执行矢量指令拆分成微指令。如上所述,在矢量的元素个数较多,而矢量执行单元1211的执行能力有限时,对于指令涉及的矢量,每次只可以处理并产生该矢量一部分元素的运算结果,这部分元素的位数即DPLEN,因此,将指令中该DPLEN位的元素运算的部分划分出来,作为一个微指令。
在拆分时,指令拆分器1301可以将待执行矢量指令拆分成(VLEN·LMUL)/DPLEN条微指令。如上所述,VLEN为矢量寄存器位宽,LMUL为待执行矢量指令中矢量占用的矢量寄存器数目,DPLEN为矢量执行单元的处理位宽。分成(VLEN·LMUL)/DPLEN条微指令时,可以从VLEN·LMUL的位宽中按照位的从低到高依次取出DPLEN位,作为一条微指令。这样,一共形成(VLEN·LMUL)/DPLEN条微指令。例如,当VLEN=128,LMUL=8时,矢量指令需要处理VLEN*LMUL=128*8=1024的宽度,而出于成本和利用效率的考虑,矢量执行单元1211的处理位宽DPLEN可能只有64。此时,则需要将待执行矢量指令拆分成VLEN*LMUL/DPLEN=1024/64=16条微指令分步执行和回写。指令拆分器1301将待执行矢量指令按照上述原则从1024位中从低到高,每次取出64位,进行后续处理。
微指令索引获取器1303基于所述拆分后的微指令所涉及的元素范围,获取所述微指令的有效元素个数索引。
有效元素个数指示一条矢量指令需要处理和更新的元素个数。一条矢量指令未必会处理和占用整个控制寄存器的所有元素,处理和占用的元素就叫做有效元素。例如,如果控制寄存器可以容纳16个元素,但有效元素个数=11,表示矢量指令只处理元素0-10这11个元素,元素12-15空闲。
有效元素个数索引不是有效元素个数,它是为了有效元素个数的比较给微指令处理的元素范围编制的索引。它不着眼于元素,而是一段元素范围。对于普通矢量指令来说,该索引反映了其分成的微指令处理的元素范围对应于矢量寄存器的哪段区间。对于仅故障优先矢量加载指令来说,它反映了仅故障优先矢量加载指令分成的微指令执行后设置的有效元素个数所位于的元素范围。
由于仅故障优先矢量加载指令需要拆分成若干条微指令执行,也就意味着每条微指令处理和回写的元素访问与拆分的DPLEN相关,即第1条拆分微指令回写最低的DPLEN位宽,第2条拆分微指令回写次低的DPLEN位宽。而相应的,若某条仅故障优先拆分微指令由于回写失败需要更新有效元素个数,更新的元素区间一定是它当前回写的DPLEN数据所对应的元素索引范围。
如图11所示,假设DPLEN为4个元素的位宽,DPLEN=64,SEW=16。拆分出的微指令A-2回写时发生访问错误,该错误的元素一定是出现在元素8~元素11之间。假设回写元素10时发送访问错误,但具体是元素8-11中的哪个元素访问错误并不重要,它们所在的元素访问都是元素8-11,同一元素范围对应同一有效元素个数索引。同理,假设DPLEN为2个元素的位宽,DPLEN=64,SEW=32。拆分出的微指令B-2回写时发生访问错误,该错误的元素一定是出现在元素4~元素5之间。假设回写元素5时发送访问错误,但具体是元素4-5中的哪个元素访问错误并不重要,它们所在的元素访问都是元素4-5,同一元素范围对应同一有效元素个数索引。
由于上述仅故障优先矢量加载指令拆分后的微指令对于有效元素个数索引的更新是可以根据SEW、LMUL以及DPLEN确定的,其他普通矢量指令也可以根据该特性来提前发射部分微指令,而不用等到仅故障优先矢量加载指令完全执行完毕再发射。只要后续的普通矢量指令拆分后的微指令涉及的元素范围在位的高低上是低于仅故障优先矢量加载指令中确认不会更新有效元素个数的元素范围的,就可以利用该仅故障优先矢量加载指令中确认不会更新有效元素个数的元素范围对应的微指令的结果,来处理该后续的普通矢量指令拆分后的微指令。例如,当仅故障优先矢量加载指令拆分出的微指令A-0已经返回信息确认不会更新有效元素个数,则表示有效元素个数不可能被更新为元素0~3的任何值,后续指令则可以将只处理元素0~3的微指令发射下来执行,直接从控制寄存器中获取当前有效元素个数值即可;同样地,若拆分指令A-1已经返回信息确认不会更新有效元素个数,后续指令则可以将只处理元素4~7的微指令发射下来执行。通过这样的方式,来提高指令执行的并行度。
如上所述,在判断后续的普通矢量指令拆分后的微指令是否可以下发下来并行执行时,考虑的是微指令处理的元素范围在位的高低上是否低于仅故障优先矢量加载指令中确认不会更新有效元素个数的元素范围,而不是一个元素,因此,单独考虑有效元素个数没有什么意义,而是采用有效元素个数索引,它代表的是一个元素范围。在该元素范围内的元素,有效元素个数索引都一样。这样,就可以通过后续的普通矢量指令拆分后的微指令处理的元素范围的有效元素个数索引与第一索引(即尚未处理完的仅故障优先矢量加载指令拆分后的微指令的有效元素个数索引)的比较,判定后续的普通矢量指令拆分后的微指令是否可以下发下来并行执行。
为此,本公开实施例设计了一种有效元素个数索引编码机制来标识当前拆分后的微指令(包括普通矢量指令和仅故障优先矢量加载指令分出的微指令)涉及的元素范围,将基于普通矢量指令当前拆分后的微指令涉及的元素范围得到的有效元素个数索引和第一索引(仅故障优先矢量加载指令拆分后的微指令的有效元素个数索引)进行比较,只有确认普通矢量指令拆分后的微指令的有效元素个数索引小于第一索引,才可以发射执行,否则需要等待对应的仅故障优先矢量加载指令拆分后的微指令确认有效元素个数的更新情况后才可以发射。
免费开放的精简指令集架构的矢量扩展指令集中,LMUL最大可以设置成8,即一条矢量指令最多需要处理并回写8个矢量寄存器。这样,能够设置的有效元素个数索引的总个数INDEX_NUM=VLEN*8/DPLEN。如果用二进制表示有效元素个数索引,则需要至少INDEX_LEN=log2(INDEX_NUM)来表示有效元素个数索引。VLEN*8/DPLEN仅仅是最大能够设置的有效元素个数索引的个数,实际上往往矢量指令不需要回写全部8个矢量寄存器。如果回写4个,就只需要VLEN*4/DPLEN个有效元素个数索引。如果回写2个,就只需要VLEN*2/DPLEN个有效元素个数索引。总之,如果假设VREG_NUM是所述待执行矢量指令要回写的矢量寄存器个数,需要的有效元素个数索引就是VLEN*VREG_NUM/DPLEN。
在本公开的一个实施例中,对于待执行矢量指令要回写的矢量寄存器个数VREG_NUM小于8的情况,并没有采用均匀编索引的方式,而是采用非均匀编索引,使得无论VREG_NUM是何值,尽量让不同VREG_NUM下方案的较高位的元素范围都维持在接近的有效元素个数索引,较低位的元素范围都维持在接近的有效元素个数索引的方式。即,如果VREG_NUM较小,就拉大两个相邻元素范围编成的有效元素个数索引值;如果VREG_NUM较大,就缩小两个相邻元素范围编成的有效元素个数索引值。这样,使得不同VREG_NUM值下,只要是在整体元素范围内处于大致一致的位置比例的元素范围,都会编码成类似的有效元素个数索引值,从而使得之后将矢量指令拆分后的微指令的有效元素个数索引与第一索引进行比较有一个合理的基础,不会因为之后的矢量指令和之前的仅故障优先矢量加载指令的VREG_NUM不同,而对比较造成不合理影响。
具体地,在一个实施例中,对于仅故障优先矢量加载指令后的普通矢量指令,微指令索引获取器1303按照如下公式1基于拆分后的微指令涉及的元素范围编码成有效元素个数索引:
vl_index(i)=8*(i+1)/VREG_NUM–1 公式1
其中,vl_index(i)为有效元素个数索引,VREG_NUM是所述待执行矢量指令要回写的矢量寄存器个数,i是所述元素范围的序号,i=0,1,2,…..,VLEN*VREG_NUM/DPLEN-1(按照位的从低到高序号递增),VLEN是矢量寄存器位宽,DPLEN是矢量执行单元的处理位宽。
由于矢量寄存器位宽为VLEN,所述待执行矢量指令要回写的矢量寄存器个数为VREG_NUM,矢量执行单元的处理位宽为DPLEN,这样就将回写的总的矢量寄存器组按照DPLEN划分成VLEN*VREG_NUM/DPLEN个元素范围,其中最低位的元素范围序号为0,倒数第二位的元素范围序号为1,……,最高位的元素范围序号为VLEN*VREG_NUM/DPLEN-1。
如果VREG_NUM=8,该元素范围序号就是有效元素个数索引,因为将VREG_NUM=8代入公式1,得到有效元素个数_index(i)=i。用二进制表示有效元素个数索引时,所述待执行矢量指令分成的微指令对应的最低序号的元素范围编码成的有效元素个数索引为0000,元素范围每高一个序号,编码成的有效元素个数索引增加0001,最高可以增加到1111,如图12所示。
如果VREG_NUM=4,将VREG_NUM=4代入公式1,得到有效元素个数_index(i)=2i+1。当i=0时,该有效元素个数索引为1;当i=1,该有效元素个数索引为3;当i=2,该有效元素个数索引为5;当i=3,该有效元素个数索引为7……当i=7,该有效元素个数索引为15。可能的二进制有效元素个数索引为0001,0011,0101,0111……1111。所述待执行矢量指令分成的微指令涉及的最低序号的元素范围编码成的有效元素个数索引为0001,元素范围每高一个序号,编码成的有效元素个数索引增加0010,最高可以增加到1111,如图12所示。从中可以看出,虽然VREG_NUM不同,但最后得到的高位的元素范围对应的有效元素个数索引与VREG_NUM=8下类似,低位的元素范围对应的有效元素个数索引也与VREG_NUM=8下类似,只不过扩大了相邻的元素范围对应的有效元素个数索引的距离。
如果VREG_NUM=2,将VREG_NUM=2代入公式1,得到有效元素个数_index(i)=4i+3。当i=0时,该有效元素个数索引为3;当i=1,该有效元素个数索引为7;当i=2,该有效元素个数索引为11;当i=3,该有效元素个数索引为15。可能的二进制有效元素个数索引为0011,0111,1011,1111。所述待执行矢量指令分成的微指令对应的最低序号的元素范围编码成的有效元素个数索引为0011,元素范围每高一个序号,编码成的有效元素个数索引增加0100,最高可以增加到1111,如图12所示。从中可以看出,虽然VREG_NUM不同,但最后得到的高位的元素范围对应的有效元素个数索引与VREG_NUM=4下类似,低位的元素范围对应的有效元素个数索引也与VREG_NUM=4下类似,只不过进一步扩大了相邻的元素范围对应的有效元素个数索引的距离。
如果VREG_NUM=1,将VREG_NUM=1代入公式1,得到有效元素个数_index(i)=8i+7。当i=0时,该有效元素个数索引为7;当i=1,该有效元素个数索引为15。可能的二进制有效元素个数索引为0111,1111。所述待执行矢量指令分成的微指令对应的最低序号的元素范围编码成的有效元素个数索引为0111,元素范围每高一个序号,编码成的有效元素个数索引增加1000,最高可以增加到1111,如图12所示。从中可以看出,虽然VREG_NUM不同,但最后得到的高位的元素范围对应的有效元素个数索引与VREG_NUM=2下类似,低位的元素范围对应的有效元素个数索引也与VREG_NUM=2下类似,只不过又进一步扩大了相邻的元素范围对应的有效元素个数索引的距离。
可以采用分数比例的方式来理解上述的编码递增的规律,当回写8个矢量寄存器时,每个64位元素范围占总元素范围的1/16,因此按最大增量16的1/16的方式递增,即每次递增1;当回写4个寄存器时,每个64位元素范围占元素范围的1/8,因此按最大增量16的1/8即2/16的方式递增,即每次递增2;当回写2个寄存器时,每个64位元素范围占总元素范围的1/4,因此按最大增量16的1/4即4/16的方式递增,即每次递增4;;当回写1个寄存器时,每个64位元素范围占总元素范围的1/2,因此按最大增量16的1/2即8/16的方式递增,即每次递增8。
该编码方式并非以绝对的元素总数来对元素范围进行编码,而是按照每条拆分后微指令涉及的元素范围占总元素范围的比例来进行编码,这样可以无视元素总数随着SEW的变化而发生的变化。此外,采用元素占比的方式来表示,更有利于部分特殊免费开放的精简指令集架构的矢量扩展指令的处理,比如变窄(narrowing)/扩宽(widening)指令以及部分掩码(mask)类指令。这些指令虽然总元素个数不变,但因为SEW的变化,回写寄存器的个数和普通指令不相同,而上述编码方式可以无视SEW的变化直接进行编码,处理简单。虽然也可以按照微指令涉及的元素范围的序号直接编码成有效元素个数索引,但是这样的编码方式下,元素的个数会随着SEW的变化而发生变化,总的元素带来的索引个数为VLEN*VREG_NUM/SEW,在SEW小于DPLEN的情况下(通常情况下SEW都会小于DPLEN),所需的索引位宽会更宽,且编码过程需要考虑SEW。
如图13所示,图13的指令B是一条普通矢量指令。PLEN为2个元素的位宽。将指令B分成的每条微指令涉及2个元素。当执行到最低的两条微指令时,微指令涉及的元素范围都对应于元素0-3这段元素范围(相邻的4个元素为一个元素范围),编成的有效元素个数索引都是0001。当执行到从低到高第3-4条微指令时,微指令涉及的元素范围都对应于元素4-7这段区间,编成的有效元素个数索引为0011。
接着,索引比较子单元1304将编码成的有效元素个数索引与第一索引进行比较,所述第一索引是矢量执行单元1211尚未处理完的仅故障优先微指令的有效元素个数索引。如果有多条仅故障优先微指令都未处理完,要与该多条仅故障优先微指令的有效元素个数索引进行比较,必须都小于的情况下,才有发射到矢量执行单元1211执行的可能。
矢量执行单元1211包括矢量运算子单元1213和第一索引记录器1212。矢量运算子单元1213执行指令发射单元130发射的待执行矢量指令拆分成的微指令。第一索引记录器1212记录第一索引,并响应于指令发射单元130的请求,发射所述第一索引。
如图13所示,指令A是一条仅故障优先矢量加载指令。指令B是跟随其后的一条拓宽(widening)指令。指令A和指令B的每条拆分指令处理并回写DPLEN位宽的元素结果。对于指令A来说,DPLEN为4个元素的位宽。假设指令A当前拆分后的一个微指令为微指令A-2,按照上文的规则,其有效元素个数索引编码为0101。已经发射到矢量运算子单元1213的拆分后的微指令为微指令A-0和微指令A-1。指令B分出的微指令B-0以及微指令B-1由于作用于元素0-3的元素范围,按照上文的规则,其有效元素个数索引编码为0001,索引比较子单元1304向第一索引记录器1212请求未执行完的A-0、A-1……的有效元素个数索引。由于编码后的有效元素个数索引0001不小于A-0的索引,因此需要等待A-0执行完毕确认有效元素个数更新信息即可发射。对于指令B拆分出的微指令B-2以及B-3,按照上文的规则,其有效元素个数索引编码为0011。索引比较子单元1304向第一索引记录器1212请求未执行完的A-0、A-1的有效元素个数索引0001和0011。由于0011不小于A-0和A-1……的索引0001和0011,因此需要等待A-0和A-1均执行完毕确认有效元素个数更新信息即可发射。指令B拆分后的微指令B-4以及B-5的有效元素个数索引为0101。索引比较子单元1304向第一索引记录器1212请求未执行完的A-0、A-1、A-2的有效元素个数索引0001、0011、0101。由于不小于A-0、A-1以及A-2的索引,因此即便A-0和A-1在矢量运算子单元1213均已执行完毕,也不能超越微指令A-2提前执行和发射,需要等待A-2也发射并执行完毕。
如果编码成的有效元素个数索引小于第一索引,微指令发射控制器1305将所述拆分后的微指令发送到所述矢量执行单元1211中的矢量运算子单元1213执行。
上述实施例中,仅进行了所述有效元素个数索引是否小于第一索引的判断。在另一实施例中,除了进行上述判断外,还要进行第一微指令是否执行完毕的判断。如图3所示,指令发射单元130还包括操作数相关性判断子单元1302,用于确定第一微指令是否执行完毕,其中,所述拆分后的微指令中的操作数依赖于所述第一微指令。微指令发射控制器1305在第一微指令已经执行完毕、且所述有效元素个数索引小于第一索引的情况下,才将拆分后的微指令发送到矢量执行单元1211执行。
拆分后的微指令的操作数依赖于第一微指令的执行结果。也就是说,第一微指令的执行结果得出后,才能执行该拆分后的微指令。在执行一个拆分后微指令之前,判断其依赖的前面的微指令是否已执行完,是满足链式执行所需要的通用条件。在通用条件判定完后,再判定本公开实施例的特定条件,即编码成的有效元素个数索引是否小于第一索引,从而就不用等待之前的仅故障优先矢量加载指令全执行完并返回有效元素个数的更新值后才开始执行,大大提高了链式执行中仅故障优先矢量加载指令后续矢量指令的运行效率。
如果有第一微指令未执行完毕,或编码成的有效元素个数索引不小于第一索引索引,微指令发射控制器1305则不能将所述拆分成的微指令发送到所述矢量执行单元1211中的矢量运算子单元1213执行,而是保持所述拆分成的微指令,直到满足条件为止。由于操作数相关性判断子单元1302、索引比较子单元1304和微指令发射控制器1305是周期性执行的,因此,在一个时钟周期不满足,可以在之后的每个时钟周期重复判定条件是否满足。直到满足条件,将所述拆分成的微指令发送到矢量运算子单元1213执行。
另外,矢量执行单元1211可能包括多个矢量运算子单元1213。所述微指令发射控制器1305可以将拆分成的多条微指令并行发送到所述多个矢量运算子单元1213并行执行,以提高执行效率。
操作数相关性判断子单元1302确定第一微指令是否执行完毕,其中,所述拆分后的微指令中的操作数依赖于所述第一微指令。
操作数是待执行矢量指令中的运算符作用的实体,它规定了待执行矢量指令中进行运算的量。例如,矢量乘法指令vmul.vv vr4,vr0,vr3表示将矢量vr4、矢量vr0、矢量vr3相乘,得到的矢量作为新的矢量vr4,这里,矢量vr4、矢量vr0、矢量vr3都是该矢量乘法指令需要的操作数。
如果某个操作数恰恰是当前微指令之前某个微指令的执行结果,那么该之前的微指令就是第一微指令。例如,在vmul.vv vr4,vr0,vr3之前有一个矢量加法指令vadd.vvvr0,vr1,vr2,其表示将矢量vr0、矢量vr1、矢量vr2相加,得到的矢量作为新的矢量vr0,因此,矢量乘法指令vmul.vv vr4,vr0,vr3中需要的操作数vr0是vadd.vv vr0,vr1,vr2的执行结果,vadd.vv vr0,vr1,vr2是第一微指令。假设矢量执行单元1211一次能处理4个元素的运算,那么处理矢量乘法指令vmul.vv vr4,vr0,vr3的元素4-7的微指令必须依赖于矢量加法指令vadd.vv vr0,vr1,vr2的元素0-3的微指令的执行结果,因此,操作数相关性判断子单元1302执行用于矢量乘法指令vmul.vv vr4,vr0,vr3的元素4-7的微指令时,就要确定矢量加法指令vadd.vv vr0,vr1,vr2的元素0-3的微指令是否执行完毕。如果是,则可以进入后续判定。否则,不能进入后续判定,因为所依赖的微指令没有处理完毕,不具备链式执行的条件。由于本步骤是周期性执行的,虽然在本时钟周期,拆分成的微指令所需要的操作数所依赖的微指令没有执行完毕,在下一个时钟周期,可能执行完毕。
如图9所示,假设指令B是矢量乘法指令vmul.vv vr4,vr0,vr3,微指令B-1是指令B中用于元素0-3处理的微指令,B-2是指令B中用于元素4-7处理的微指令,B-3是指令B中用于元素8-11处理的微指令……指令A是矢量加法指令vadd.vv vr0,vr1,vr2,微指令A-1是指令A中用于元素0-3处理的微指令,A-2是指令A中用于元素4-7处理的微指令,A-3是指令A中用于元素8-11处理的微指令……在时钟周期1,可以发射微指令A-1进行处理。在时钟周期2,可以处理微指令A-2。同时,微指令B-1所依赖的之前的微指令A-1已处理完,也可以处理微指令B-1。因此,在时钟周期2可以同时处理微指令A-2和B-1。在时钟周期3可以同时处理微指令A-3和B-2……达到链式执行的效果,有效减少操作数相关性带来的等待延时。
在操作数相关性判断子单元1302确定拆分成的微指令所需要的操作数所依赖的微指令是否执行完毕时,可以先获取拆分后的微指令中的操作数,再获取之前拆分后的微指令中产生所述操作数的微指令,再确定获取的微指令是否执行完毕。如上例中,对于矢量乘法指令vmul.vv vr4,vr0,vr3的拆分出的元素4-7的微指令,获取其需要的操作数vr4、vr0、vr3,分别针对vr4、vr0、vr3查找之前拆分出的微指令中哪些微指令的执行结果涉及vr4、vr0、vr3,结果找到矢量加法指令vadd.vv vr0,vr1,vr2拆分偶的元素0-3的微指令。最后,确定vadd.vv vr0,vr1,vr2拆分后的元素0-3的微指令已经执行完毕。
如图14所示,根据本公开的一个实施例,提供了一种矢量执行加速方法,其由指令发射单元130执行,包括:
步骤310、将待执行矢量指令拆分成微指令;
步骤320、基于所述拆分后的微指令所涉及的元素范围,获取所述微指令的有效元素个数索引;
步骤330、将获取的有效元素个数索引与第一索引比较,所述第一索引是尚未处理完的仅故障优先微指令的有效元素个数索引;
步骤340、在所述有效元素个数索引小于第一索引的情况下,将拆分后的微指令发送到矢量执行单元执行。
可选地,在步骤340之前,所述方法还包括:确定第一微指令是否执行完毕,其中,所述拆分后的微指令中的操作数依赖于所述第一微指令;所述步骤340包括:在第一微指令已经执行完毕、且所述有效元素个数索引小于第一索引的情况下,才将拆分后的微指令发送到矢量执行单元执行。
可选地,所述步骤340包括按照以下公式计算所述有效元素个数索引:
vl_index(i)=8*(i+1)/VREG_NUM–1,
其中,vl_index(i)为所述有效元素个数索引,VREG_NUM是所述待执行矢量指令要回写的矢量寄存器个数,i是所述元素范围的序号,i=0,1,2,…..,VLEN*VREG_NUM/DPLEN-1,其中,VLEN是矢量寄存器位宽,DPLEN是矢量执行单元的处理位宽。
可选地,如果VREG_NUM=8,序号最低的所述元素范围对应的有效元素个数索引为0000,元素范围每高一个序号,所述有效元素个数索引增加0001。
可选地,如果VREG_NUM=4,序号最低的所述元素范围对应的有效元素个数索引为0001,元素范围每高一个序号,所述有效元素个数索引增加0010。
可选地,如果VREG_NUM=2,序号最低的所述元素范围对应的有效元素个数索引为0011,元素范围每高一个序号,所述有效元素个数索引增加0100。
可选地,如果VREG_NUM=1,序号最低的所述元素范围对应的有效元素个数索引为0111,元素范围每高一个序号,所述有效元素个数索引增加1000。
可选地,所述确定第一微指令是否执行完毕,包括:
获取拆分后的微指令中的操作数;
获取之前拆分出的微指令中产生所述操作数的微指令;
确定获取的微指令是否执行完毕。
可选地,在确定第一微指令是否执行完毕之后,所述方法还包括:在第一微指令未执行完毕、或者所述有效元素个数索引小于第一索引的情况下,保持所述拆分后的微指令。
本申请还公开了一种包括存储于其上的计算机可执行指令的计算机可读存储介质,所述计算机可执行指令在被处理器执行时使得所述处理器执行本文所述的各实施例的方法。
需要领会,以上所述仅为本发明的优选实施例,并不用于限制本发明,对于本领域技术人员而言,本说明书的实施例存在许多变型。凡在本发明的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。
应该理解,本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同或相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于方法实施例而言,由于其基本相似于装置和系统实施例中描述的方法,所以描述的比较简单,相关之处参见其他实施例的部分说明即可。
应该理解,上述对本说明书特定实施例进行了描述。其它实施例在权利要求书的范围内。在一些情况下,在权利要求书中记载的动作或步骤可以按照不同于实施例中的顺序来执行并且仍然可以实现期望的结果。另外,在附图中描绘的过程不一定要求示出的特定顺序或者连续顺序才能实现期望的结果。在某些实施方式中,多任务处理和并行处理也是可以的或者可能是有利的。
应该理解,本文用单数形式描述或者在附图中仅显示一个的元件并不代表将该元件的数量限于一个。此外,本文中被描述或示出为分开的模块或元件可被组合为单个模块或元件,且本文中被描述或示出为单个的模块或元件可被拆分为多个模块或元件。
还应理解,本文采用的术语和表述方式只是用于描述,本说明书的一个或多个实施例并不应局限于这些术语和表述。使用这些术语和表述并不意味着排除任何示意和描述(或其中部分)的等效特征,应认识到可能存在的各种修改也应包含在权利要求范围内。其他修改、变化和替换也可能存在。相应的,权利要求应视为覆盖所有这些等效物。