一种低功耗的长指令字指令存储器及其优化功耗的方法与流程

文档序号:14995893发布日期:2018-07-24 17:41阅读:351来源:国知局

本发明属于微处理器技术领域,具体涉及一种微处理器的指令存储器及其优化功耗的方法。



背景技术:

指令存储器存储了源程序的指令代码,处理器根据运行时的程序计数器(PC)值从指令存储器中获取指令。现代微处理器的指令存储器一般由静态随机存储器(SRAM)构成,访问SRAM会造成SRAM核心进行充电和放电,以及一些外围电路的功耗。研究表明在嵌入式领域指令存储器功耗约为微处理器的功耗的30~40%,以至于指令存储器成为了微处理器的能量消耗主要部件。高能耗对微处理器特别是嵌入式应用领域的微处理器提出了挑战。因此,研究降低指令存储器功耗有十分重要的现实意义。

图1展示了传统的6级流水线的微处理器结构图。包括了取指令级、译码级、执行级、访存储器级、对齐级和写回级。

在传统的微处理器架构中,取指令级用到的指令存储器的位宽为1条指令,从而每次取新指令时都需要根据指令计数器(PC)去访问指令存储器,从而导致SRAM固有的充放电功耗以及外围电路的功耗。扩展后的指令存储器位宽为4,一次访问指令存储器可以取出4条指令,并且这四条指令被SRAM输出的锁存器锁存,下次取指令时,如果需要的指令已经被取出锁存,则不需要再去访问指令存储器的核心,从而避免了占据SRAM大部分功耗的充放电功耗,而只需要从锁存器中选择即可。实验表明4指令宽度的SRAM的访问功耗约为1指令宽度SRAM的2倍,从而可以期望获得50%的功耗降低。实际上由于分支指令会导致一些取出的指令作废,使得实际的降低不会这么明显,本发明还提出了软件优化算法来优化最坏情况下本发明技术的性能。



技术实现要素:

本发明的目的在于提供一种可大幅降低功耗的指令存储器以及优化功耗的方法。

本发明通过扩展指令存储器的位宽为4条指令,可以减少对指令存储器的访问的频率,从统计上减少了平均获取一条指令引起的功耗,从而降低了指令存储器的访问功耗,由于指令存储器的功耗占据了整个处理器功耗的相当大比例(30~40%),从而也明显降低了整个处理器的功耗。

本发明提出的指令存储器,是以现有的微处理器的架构为基础(即微处理器结构如图1所示,包括取指令级、译码级、执行级、访存储器级、对齐级和写回级),将指令存储器的位宽从原始1条指令扩展到4条指令,即将相邻的4条指令并为一条长指令字,每次访问指令存储器可以获取4条指令;相应地依次对指令存储器的地址信号、选择信号、时钟信号进行修改,具体的修改方式为:1、对于指令存储器的地址信号,采用处理器指令计数器(PC)除去低二位的值进行选择(因为在本发明中指令存储器的位宽从1条指令扩展到4条指令);2、对于指令存储器的选择信号,在原始设计中,指令存储器的选择信号一直有效,在本发明中,只有当需要访问指令存储器时,选择信号才有效(具体需要访问指令存储器的情况有两种,其一是程序计数器PC的低二位为2’b00,其二为当程序执行遇到分支指令时);3、对于指令存储器的时钟信号,原始设计中该时钟信号一直有效,本发明中,只有出现2中所述的需要访问指令存储器的情况时,才将指令存储器的时钟打开,否则将其利用门控时钟进行屏蔽,最终实现指令存储器的位宽扩展。这样,当微处理器不需要访问指令存储器、而从指令存储器的输出锁存器中获取指令时,选择信号和时钟信号均被无效,从而减小了指令存储器的功耗。由于本发明把指令存储器的位宽从原始1条指令扩展到4条指令,因此称其为长指令字指令存储器。

基于上述长指令字指令存储器,本发明还提出优化功耗的方法,该方法通过软件工具实现。该软件能够在编译时期静态地遍历整个汇编程序,找到由于分支导致的最坏情况的出现,并且按照本发明的方法,进行代码优化,使得调整后的代码能够保证本发明的功耗小于现有技术功耗。该方法的具体步骤为:

1、第一个while循环首先来确定那些在长指令字第一个槽的分支指令,如果找到了,就把label这个容器的对应的位置置为1,否则为0,为下一个循环做准备;

2、第二个循环则重新开始扫描汇编代码,如果当前指令是分支目的地,并且是位于长指令字的第4个槽(即最后一个槽),并且分支到这里的指令对应的label的位置为1(表示该分支指令在长指令字第一个槽),那么就表示最坏的情况出现了(最坏情况在图4中给出);

3、具体的优化策略是用一个nop代替这条目的地指令,并且将新的汇编输出到输出文件中;

4、按照步骤(1)、(2)和(3),重复扫描汇编代码,直到原始的汇编代码全部扫描完毕。

本发明将指令存储器的位宽扩充为4条指令,最理想的情况下,存储器核心充放电一次可以提供4条指令,从而减少了访问了存储器核心充放电的次数,对于4位宽长指令字存储器,核心充放电的功耗相对1位宽指令字存储器增加了2倍,从而可以获得平均功耗的降低。另外,本发明还针对程序中可能出现的分支导致这种技术性能降低进行了优化处理,保证本发明技术在有分支的情况下仍然能不差于原始技术的设计。

与现有的架构相比,本发明提供的长指令字指令存储器及优化功耗的方法,能够在几乎不增加硬件开销、并且不影响处理器工作最高频率的情况下,有效地降低大部分嵌入式应用的访存功耗,从而降低了整个处理器的功耗。

附图说明

图1是传统的6级流水线微处理器架构。

图2是长指令字存储器逻辑和架构设计。

图3是评估函数f的定义和说明。

图4是最坏情况的实例和优化策略。

具体实施方式

下面结合附图和实例,进一步描述长指令字指令存储器及优化功耗的方法。

图2 展示了长指令字存储器逻辑和架构设计,首先,指令存储器的位宽从原先的1条指令扩展为现在的4条指令,原先一次取出1条指令(32位)现在可以取出128位的4条指令,这样,原先用指令计数器PC现在改进为PC的取出低二位的部分,定义了存储器的时钟m_clk和存储器选择信号m_ce,当PC的低二位为00或者遇到分支指令时,必须访问指令存储器,因此此时中间变量存储器访问mem_acc为1有效,否则不需要访问存储器,mem_acc为0无效,如果mem_acc有效,此时,m_ce有效,反正m_ce无效,如果mem_acc有效,则m_clk必须启动,否则被门控关掉。取出的指令被锁存在输出的寄存器/锁存器,然后根据PC的低二位来选择某一个32位指令被选中。

图3展示了评估函数f的定义,f是用来评估长指令字技术(LIWM)相对于原始的单指令字存储(1IWM)是更优或者更差。这里的公式的参数定义见图3所示,具体为:

f=valid_inst_cnt - mem_acc_cnt * pwr_ratio

其中,mem_acc_cnt表示指令存储器访问次数;

valid_inst_cnt表示有效的指令数目;

pwr_ratio表示LIWM访问功耗/ 1IWM访问功耗;

当f > 0时,表明LIWM比1IWM消耗少的功耗;

当f < 0时,表明LIWM比1IWM消耗多的功耗。

如果按照该公式计算出的f大于0,则表明LIWM比1IWM更优,否则LIWM比1IWM更差。

图4展示最坏情况和优化策略。首先在(a)中可以看出,如果分支指令出现在长指令字的第一个槽,并且跳转到目的地的指令在下一个长指令字的最后一个槽,那么,有效的指令(无阴影部分的指令)数目为3,而却要访问两次存储器,造成f小于0,这种情况下本发明的技术将比原始技术更差。然后在(b)中给出了优化的策略,即在分支目的地前插入了以nop(空指令),将目的地指令排到下一个长指令,(b)中分情况讨论得到的结果显示,不论在何种情况下,f总是不小于0,从而可以保证本发明的技术不会比原始技术差。

附录 为本发明优化功耗的方法的代码,展示了通过编译时静态扫描汇编代码,发现最坏情况,并且自动优化最坏情况的算法。该算法第一个while循环首先来确定那些在长指令字第一个槽的分支指令,如果找到了,就把label这个容器的对应的位置置为1,否则为0,为下一个循环做准备。第二个循环则重新开始扫描汇编代码,如果当前指令是分支目的地,并且是位于长指令字的第4个槽(最后一个槽),并且分支到这里的指令对应的label的位置为1(表示该分支指令在长指令字第一个槽),那么就表示最坏的情况出现了(最坏情况在图4中给出),优化策略就是用一个nop代替这条目的地指令,并且将新的汇编输出到输出文件中。程序不停地执行直到原始的汇编代码全部扫描完毕。

附录

算法: 最坏情况优化

输入: 源程序汇编代码src_inst

参数: 计数器i, 容器label, 临时指令inst_tmp

输出: 优化后的汇编代码 opt_inst

初始化: 甚至i 为 0, 清空 label, 设置 src_inst 到开始位置

00: while(!src_inst.end())

01: inst_tmp=src_inst.getOneInst();

02: if(inst_tmp.isBranch()) // 如果分支在指令字的第一个槽,设置 label 为1

03: label[inst_tmp.getLabel()] = i== 0 ? 1 : 0; i = i== 3 ? 0 : i+ 1; // 更新 label, i

04: endif

05: endwhile

// 重置 i 为 0,src_inst 到开始位置

06: while(!src_inst.end())

07: inst_tmp=src_inst.getOneInst();

08: if(inst_tmp.isBranchTarget() && i== 3 && label[inst_tmp.getLabel()]) // 最坏情况

09: opt_inst.putOneInst(nop);opt_inst.putOneInst(inst_tmp); i = 1; //插入一个 nop

10: else

11: opt_inst.putOneInst(inst_tmp); i = i== 3 ? 0 : i+ 1; // 更新 i

12: endif

13: endwhile。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1