发明内容
本发明内容被提供以引入还将在下文的具体实施方式中进行描述的简化方式的概念的选择。该发明内容不是旨在识别要求保护的主题的关键特征或重要特征,也不旨在用于帮助确定要求保护的主题的范围。
描述了改进的/修改的返回堆栈缓存(RSB)。在一个实施例中,RSB被修改以存储索引值而不是地址。当函数被调用时,跟随函数调用的地址被存储在查询表中,并且在该索引地址被存储的索引被压入到RSB。当函数返回时,索引从RSB弹出并且用于识别在查询表中的地址。在另一个实施方式中,RSB被修改使得每个条目包括两个或多于两个地址段(address slot)。当函数被调用时,跟随函数调用的地址被压入到RSB并且被存储在RSB中的顶部条目中的地址段中选择的一个地址段中。条目内的一个或多个指针位被设置以指示地址被存储在那个段中。
第一方面提供了操作处理器的方法,方法包括:响应于函数调用,将跟随函数调用的地址存储在查询表中的条目中,并且将条目的索引压入到返回堆栈缓存中;并且响应于函数返回,将最近写入的索引从返回堆栈缓存中移除并且访问在查询表中的移除的索引处存储的地址。
根据第一方面的方法,其中,相比于地址,索引包括数量少的位。
根据第一方面的方法还包括:每次在所述处理器中做出预测时,存储整个所述返回堆栈缓存的副本和指向所述返回堆栈缓存的顶部的指针。响应于识别到误预测,使用在做出所述预测时存储的数据来恢复所述返回堆栈缓存,所述数据至少包括返回堆栈缓存的子集和指向所述返回堆栈缓存的顶部的指针。响应于识别到误预测:移除或无效所述查询表中没有被在所恢复的返回堆栈缓存中引用的每个条目。
根据第一方面的方法还包括:每次在所述处理器中做出预测时,存储所述返回堆栈缓存的子集和指向所述返回堆栈缓存的顶部的指针。
根据第一方面的方法还包括:响应于函数调用,并且在存储跟随所述函数调用的所述地址之前,执行以下操作:确定所述查询表是否是满的;以及响应于确定所述查询表是满的,使用替换算法移除或无效所述查询表中的条目。其中所述替换算法在所述查询表中选择最近最少使用的条目。
根据第一方面的方法还包括:响应于函数返回指令被提交,从所述查询表中移除或无效对应于该函数的条目。
根据第一方面的方法,其中所述处理器是无序处理器。
第二方面提供了处理器,其包括:取指级;以及被布置为存储返回堆栈缓存和查询表的资源,其中取指级被布置为:响应于函数调用,将跟随函数调用的地址存储在查询表中的条目中,并且将条目的索引压入到返回堆栈缓存中;并且响应于函数返回,将最近写入的索引从返回堆栈缓存中移除并且访问在查询表中的移除的索引处存储的地址。
根据第二方面的处理器,其中相比于地址,索引包括数量少的位。
根据第二方面的处理器,其中在所述返回堆栈缓存中的每个条目具有相关联的有效位,以指示所述条目是有效的还是无效的。
根据第二方面的处理器还包括分支预测器,并且其中所述取指级被布置为每次在所述处理器中做出预测时,存储整个所述返回堆栈缓存的副本和指向所述返回堆栈缓存的顶部的指针。其中所述取指级还被布置为:响应于识别到误预测,使用在做出所述预测时所存储的数据来恢复所述返回堆栈缓存,所述数据至少包括返回堆栈缓存的子集和指向所述返回堆栈缓存的顶部的指针。其中所述取指级还被布置为:响应于识别到误预测,移除或无效所述查询表中没有被在所恢复的返回堆栈缓存中引用的每个条目。
根据第二方面的处理器还包括分支预测器,并且其中所述取指级被布置为每次在所述处理器中做出预测时,存储所述返回堆栈缓存的子集和指向所述返回堆栈缓存的顶部的指针。
根据第二方面的处理器,其中所述取指级还被布置为响应于函数调用并且在存储跟随所述函数调用的所述地址之前,执行以下操作:确定所述查询表是否是满的;以及响应于确定所述查询表是满的,使用替换算法移除或无效所述查询表中的条目。其中所述替换算法在所述查询表中选择最近最少使用的条目。
根据第二方面的处理器,其中所述取指级还被布置为:响应于函数返回指令被提交,从所述查询表中移除或无效对应于该函数的条目。
根据第二方面的处理器,其中所述处理器是无序处理器。
第三方面提供了在其上编码有计算机可读程序代码的用于产生根据第二方面的处理器的计算机可读存储介质。
第四方面提供了具有在其上编码的计算机可读程序代码的用于产生被配置为执行第一方面的方法的处理器的计算机可读存储介质。
第五方面提供了操作处理器的方法,方法包括:响应于函数调用,将跟随函数调用的地址存储在修改的返回堆栈缓存中的顶部条目中的多个地址段中的一个地址段中,并且更新堆栈指针和堆栈指针位以指向其中存储该地址的条目和地址段,并且在条目中设置一个或多个指针位的值,该一个或多个指针位包括第一部分和第二部分,第一部分至少指示在该条目中最近写入的地址段,第二部分指示对于在条目中的多个地址段中的每个地址段,在该条目中的多个地址段中的特定的一个地址段被写入时在先前的条目中最近写入的地址段;并且响应于函数返回,从由堆栈指针和堆栈指针位识别的修改的返回堆栈缓存中的条目中的地址段读取地址,更新堆栈指针以指向先前的条目并且基于条目的指针位的第二部分和地址读取自的地址段来更新堆栈指针位。
根据第五方面的方法,其中跟随所述函数调用的所述地址被存储在所述多个地址段中选择的一个地址段中,其中所述地址段使用替换算法进行选择。其中所述替换算法在所述条目中选择最近最少使用的地址段。
根据第五方面的方法还包括:每次在所述处理器中做出预测时,存储所述修改的返回堆栈缓存的所述堆栈指针和所述堆栈指针位。
根据第五方面的方法,其中所述修改的返回堆栈缓存包括多个条目,并且每个条目包括两个地址段和一个或多个指针位。其中所述一个或多个指针位包括:第一部分,所述第一部分指示所述两个地址段中的哪个地址段被最近写入;以及第二部分,所述第二部分包括与第一地址段相关联的至少一位和与第二地址段相关联的至少一位,其中与地址段相关联的位被布置为指示在所述特定的地址段被写入时在所述修改的返回堆栈缓存中的所述先前的条目中最近写入的地址段。
根据第五方面的方法,其中所述修改的返回堆栈缓存包括多个条目,并且每个条目包括多个地址段和针对每个地址段的一个或多个指针位。其中针对每个地址段的所述一个或多个指针位包括:第一部分,所述第一部分指示所述地址段是否是被最近写入;以及第二部分,所述第二部分被布置为指示在所述地址段被写入时在所述修改的返回堆栈缓存中的所述先前的条目中最近写入的地址段。
根据第五方面的方法,其中所述处理器是无序处理器。
第六方面提供了处理器,其包括:取指级;以及被布置为存储修改的返回堆栈缓存的资源,其中该取指级被布置为:响应于函数调用,将跟随函数调用的地址存储在修改的返回堆栈缓存中的顶部条目中的多个地址段中的一个地址段中,更新堆栈指针和堆栈指针位以指向其中存储该地址的条目和地址段,并且设置在条目中的一个或多个指针位的值,所述一个或多个指针位包括第一部分和第二部分,第一部分至少指示在条目中最近写入的地址段,第二部分指示对于在该条目中的多个地址段中的每个地址段,在该条目中的多个地址段中的特定的一个地址段被写入时在先前的条目中最近写入的地址段;并且响应于函数返回,从由堆栈指针和堆栈指针位识别的修改的返回堆栈缓存中的条目中的地址段读取地址,更新堆栈指针以指向先前的条目和基于该条目的指针位的第二部分和地址读取自的地址段来更新堆栈指针位。
根据第六方面的处理器,其中跟随所述函数调用的所述地址存储在所述多个地址段中选择的一个地址段中,其中使用替换算法来选择所述地址段。其中所述替换算法在所述条目中选择最近最少使用的地址段。
根据第六方面的处理器还包括分支预测器,并且所述取指级还被布置为,每次在所述处理器中做出预测时,存储所述修改的返回堆栈缓存的所述堆栈指针和所述堆栈指针位。
根据第六方面的处理器,其中所述修改的返回堆栈缓存包括多个条目,并且每个条目包括两个地址段和一个或多个指针位。
根据第六方面的处理器,其中所述修改的返回堆栈缓存包括多个条目,并且每个条目包括多个地址段和针对每个地址段的一个或多个指针位。
根据第六方面的处理器,其中所述处理器是无序处理器。
第七方面提供了具有在其上编码的计算机可读程序代码的用于产生根据第六方面的处理器的计算机可读存储介质。
第八方面提供了具有在其上编码的计算机可读程序代码的用于产生被配置为执行根据第五方面的方法的处理器的计算机可读存储介质。
本文描述的方法可以被计算机执行,所述计算机被配置具有以机器可读形式存储在有形存储介质上的软件,例如以包括用于配置计算机以执行所描述的方法的组成部分的计算机可读程序代码的计算机程序的形式,或以包括当程序在计算机上运行时适于执行本文描述的方法中的任何方法的所有步骤的计算机程序代码工具的计算机程序的形式,并且其中计算机程序可以在计算机可读存储介质上体现。有形的(或非暂时的)存储介质的示例包括:磁盘、拇指驱动器、储存卡等,并且不包括传播的信号。软件可以适合于在并行处理器或串行处理器上执行使得可以以任何合适的顺序执行或同时执行方法步骤。
本文描述的硬件组件可以通过具有在其上编码的计算机可读程序代码的非暂时的计算机可读存储介质来产生。
这里承认的是,固件和软件可以单独使用且是有价值的。旨在包括在“非智能的”或标准的硬件上运行或控制“非智能的”或标准的硬件的软件以执行期望的功能。还旨在包括“描述”或限定硬件的配置的软件(例如HDL(硬件描述语言)软件,如用于设计硅芯片,或用于配置通用可编程芯片)以执行期望的功能。
如对于技术人员将明显的是,优选的特征可以适当地组合,并且可以与本发明的方面中的任何方面组合。
具体实施方式
下文仅仅通过示例的方式来描述本发明的实施例。尽管这些示例不是其中可以实现本发明的仅有的方式,但是它们表示申请人当前已知的实施本发明的最好的方式。该描述阐述了示例的功能和用于构造和操作该示例的步骤的顺序。然而,可以通过不同的示例来完成相同的或等同的功能和顺序。
堆栈通常用于提供暂时存储的区域并且被实施为后进先出(LIFO)存储资源(其可以可替代地称为先入后出FILO),使得数据被严格以与该数据被添加到该堆栈的顺序相反的顺序从该堆栈移除。该堆栈可以被认为从堆栈原点向上增长或向下增长;然而,在这两种情况下,堆栈的顶部(其是在堆栈上最近被添加的元素)可以被通常指向下一个未使用的条目的堆栈指针识别。堆栈可以是软件堆栈;然而,下文描述的堆栈在硬件中实施并且使用堆栈的概念以模仿(以对软件透明的方式)嵌套函数调用编程范例的行为。这将在下文进行更加详细的描述。
为了下文描述的目的,堆栈并且尤其是返回堆栈缓存(RSB)被认为是向上增长的,使得当数据被压入到堆栈中时堆栈指针的值增加,且当数据从堆栈中弹出时堆栈指针的值减小。然而,应当理解的是,如果堆栈和/或RSB被认为是向下增长的(其中当数据被压入到堆栈时,堆栈指针的值减小,且当数据从该堆栈弹出时,堆栈指针的值增加),则本文描述的方法是同样适用的。
如上所述,返回堆栈缓存(RSB)(也被称为返回地址堆栈(RAS))可以用于根据函数预测返回地址。然而,在使用推测的地方会出现问题,因为误预测可能导致RSB被破坏。针对做出的每次预测,存储指向RSB的顶部的指针,保存堆栈的队列,但是通过从RSB的推测性弹出,信息可能仍然被丢失。通过存储在RSB的顶部的一个或多个条目连同到顶部的指针,其中每次预测使推测性弹出能够被恢复,但是需要更多的存储空间(其对应于处理器内的硅的区域)。为了确保没有信息由于推测性弹出而丢失,整个RSB可以在每次预测被做出时被存储;然而,因为假定RSB通常包括8-16个条目,这些条目中的每个条目包括32位地址时产生的存储需求(其可以显著地增加设备的区域),这在很多应用中是不实际的。
解决RSB的破坏的问题的两个实施例在下文进行了描述,并且两者都涉及使用改进的/修改的RSB。在第一实施例中,RSB被修改使得其不包括地址而是包括到新数据结构(或查询表)的索引,该新数据结构用于存储返回地址。其具有这样的效果,即RSB在大小上更小(例如,它包括8-16个条目,这些条目中的每个条目包括log2(表_大小)数量的位,其中表_大小是在查询表中的条目的最大数量),并且因此,在一些示例中,整个RSB可以随着每次预测被存储,而不对设备的大小有显著影响。
在第二实施例中,RSB的结构被修改以包括每个条目两个(或多个)地址和至少一个指针位。当地址被添加到RSB时,它被存储在RSB中的顶部条目中的两个(或多个)地址段中的一个地址段中,并且该指针位被设置为指示其中地址被存储的段。当地址从RSB“弹出”时,指针位被复位,使得它不再指向弹出的地址(并且堆栈指针被以通常的方式更新),但是弹出的地址没有被从RSB中移除。当地址被随后添加到RSB时,它被存储在RSB中的最顶部条目中的地址段中的不同的地址段中,并且指针位被设置以指示其中地址被存储的段,使得最近弹出的地址不会被重写。在该解决方案中,针对每次预测,指向该堆栈的顶部的指针连同该堆栈的顶部条目的指针位被存储;然而,针对每次预测,没有必要存储整个RSB或在RSB的顶部的条目。
使用本文描述的任一实施例,由RSB的破坏引起的误预测被减少或消除。在第一实施例中,针对每次预测,修改的RSB被存储,其可以随后在误预测发生时被使用。在第二实施例中,使用了具有不同结构的RSB,其减少了RSB的破坏的可能性。
图1示出了其中可以实施本文描述的方法的示例无序处理器100的示意图。在该示例中,处理器100是单线程处理器,然而,该方法还适用于多线程处理器(其中每个线程将保持单独的RSB)。
处理器100包括取指级102、译码和重命名级104、重新排序缓存106、提交级108、分支预测器110、一个或多个功能单元112(其每个包括一个或多个执行管道)和RSB 114(其可以被存储在处理器100内的触发器中)。
取指级102被配置为从如由程序计数器(PC)指示的程序(以程序顺序)读取指令。取指级102还压入或弹出条目到RSB 114(其可以是取指级102的一部分)。其中使用了新的查询表(例如在本文描述的第一实施例中的查询表),这可以被存储在取指级102中或RSB114的资源中或由取指级102维护。
一旦指令被读取,则它被提供到译码和重命名级104,其被布置为解释指令和执行寄存器重命名(例如使用寄存器重命名映射/表)。
在指令通过译码和重命名级104之后,其被插入到重新排序缓存106(ROB)中并且被分发到功能单元112用于执行。重新排序缓存106是使指令能够被无序执行但有序提交的缓存。重新排序缓存106以程序顺序保持插入到其中的指令,但是ROB 106内的指令可以被功能单元112无序执行。从重新排序缓存106输出的指令被提供到提交级108,其将指令的结果提交到寄存器/存储器。
处理器100还包括分支预测器110,其被配置为预测在已知的指令(例如分支指令)引起可能的流向改变的情况下程序流程将采取哪个方向。分支预测器110对不被RSB 114预测的指令的推测负责。存储在RSB 114中的返回地址独立于任何分支预测目标并且被取指级102提供。在各个示例中,返回地址通常是函数调用地址+4。
分支预测是有用的,因为它使指令能够在分支指令的结果被知晓之前被处理器100推测地执行。分支预测器110可以接收来自取指级102与译码和重命名级104的关于新的指令的输入和来自功能单元112的输入。
当分支预测器110精确地预测程序流程时,这提高了处理器100的性能。然而,如果分支预测器没有准确地预测分支方向,则随后误预测发生,其需要在程序可以继续之前被校正。为了对误预测进行校正,发送到ROB106的推测的指令被放弃,并且取指级102开始从正确的程序分支提取指令。如下文更加详细描述的,这可能涉及取指级102使用存储的RSB版本和存储的相关联的指向RSB的顶部的指针来恢复RSB(例如在本文描述的第一实施例中的情况),或可替代地,可以使用存储的指向RSB的顶部的指针和存储的相关联的RSB中的顶部条目的指针位来恢复RSB(例如在本文描述的第二实施例中的情况)。
每个功能单元112负责执行指令并且可以被配置为执行特定类型的指令。例如,功能单元112可以包括加载-存储单元、整数单元、浮点单元(FPU)、数字信号处理(DSP)/单指令多数据(SIMD)单元或乘法累加(MAC)单元中的一个或多个。除此之外,加载-存储单元将数据读取到L1高速缓存与存储器和从L1高速缓存与存储器中写入数据。在一些情况下,加载-存储单元可以计算地址并且其可以(或不可以)包括L1高速缓存并且执行数据/标签RAM查询。整数单元执行整数指令,FPU执行浮点指令,DSP/SIMD单元具有在多个数据点上同时执行相同的操作的多个处理元件,并且MAC单元计算两个数的乘积并且将该乘积添加到累加器。功能单元内的管道可以具有不同的长度和/或复杂性。例如,FPU管道通常长于整数执行管道,因为它通常执行更复杂的操作。
应当理解的是,其他的处理器可能不包括图1中示出的所有的功能元件(即可以省略图1中示出的功能元件中的一个或多个),并且在一些示例中可以包括图1中没有示出的附加的功能元件、和/或在功能元件之间的附加的连接(例如,在一些示例中可能是功能元件112和RSB 114之间的连接)。例如,当执行从译码和重命名级104接收的指令时,每个功能单元112执行读取和写入到在一个或多个共享的寄存器文件(图1中未示出)中的物理寄存器。为了减少时延,最近写入的寄存器可以被存储在寄存器文件高速缓存中(图1中同样未示出)。
可以参考附图2-6来更加详细地描述第一实施例。图2示出了三个示例流程图201-203,其可以在图1中示出的处理器100中实施,并且其涉及RSB的操作和使用。图3示出了修改的RSB和新的数据结构(其还可以称为查询表或全相联高速缓存)的示意图。
如第一流程图201中所示,当函数被调用时(框212),在新的查询表中的未使用的条目被识别,并且跟随函数调用的地址被存储在该条目中(框214)。其中该地址被存储(在新的查询表中)的条目的索引然后被压入到RSB(框216)。这在示出了RSB 311和新的查询表312的图3中的第一示意图301中示出。已经使用了在新的查询表中的第一条目313,因此地址(在本示例中被标记为“地址01”)被存储在第二条目314中。第二条目314的索引(在本示例中被标记为“索引02”)然后被压入到RSB311并且包括在RSB 311中的新的顶部条目315。RSB 311的堆栈指针被更新(如通过箭头316所指示的),作为新的条目的结果以指向下一个未使用的条目317。
如果响应于另一个函数调用(例如用于嵌套函数)而随后重复流程图201的方法,则另一个地址(‘地址02’)被存储在新的查询表312(在框214中)中,如图3中的第二示意图302中所示,并且其中它被存储的条目321的索引(‘索引03’)被压入到RSB 311(在框216中)。在RSB 311中的该新的条目322现在是顶部条目,并且RSB 311的顶部条目和堆栈指针被更新(如通过箭头323所指示)作为新的条目的结果以指向下一个未使用的条目324。
如上所述,流程图201的方法可以被图1中示出的处理器100中的取指级102实施,并且新的查询表312可以被存储在RSB 114的资源中或图1中示出的取指级102内。
如果随后做出了预测(框232),如图2中的第三流程图203中所示,则整个RSB 311可以连同指向RSB中的顶部条目(即条目322)的指针被存储(框234)。可替代地,被存储的指针可以指向下一个未使用的条目(即条目324)。如上所述,该流程图可以被图1中示出的处理器100中的取指级102来实施,并且RSB的存储的副本和指针可以被存储在处理器100中的寄存器/RAM中(例如连同关于做出的每个分支预测的信息一起存储)。如果预测(在框232中做出)随后被发现是误预测,则使用(在框234中)被存储的信息来恢复RSB。指针被存储(在本示例中),同时整个RSB被存储(在框234中),因为如果RSB变满,则RSB可以被允许环绕。在其它示例中(例如,其中RSB没有环绕或在其它情况下),可能没有必要存储指针;然而,即使其中指针被存储,附加的存储需求是很小的(即log2(RSB大小))。
因为在该实施例中的RSB存储索引而非完整的地址,其中索引的大小(即位数)显著地小于完整的地址(其通常是32位)的大小,每次预测被做出时存储整个RSB(如流程图203的框234中所示)不需要庞大的存储量。如上所述,索引的大小取决于查询表的大小(例如索引大小=log2(表_大小),其中表_大小是在查询表中的条目的最大数量)。
然而,在可替代的示例中,每次预测做出时,RSB的子集可以被存储(框236),其中术语“子集”指的是适当的子集。通过仅仅存储RSB的子集连同指向顶部条目的指针,这进一步减少了所需的存储。在示例中,可以针对每次预测存储顶部的M个条目(其中M是自然数,例如M=3)连同指向顶部条目的指针。使用该信息,如果发生误预测,则可以对RSB进行部分地重构。
响应于函数返回(框222),如图2中的第二流程图202中所示,顶部条目(即顶部索引)从RSB中弹出(框224),并且该索引用于查询在新的查询表中的地址(框226)。如上所述,该地址是跟随现在已经返回的函数调用的地址。参考图3中的第二示意图302中示出的示例,顶部索引(索引03)从RSB 311中弹出(在框224中)并且用于查询地址(在新的查询表312中的地址02)(在框226中)。
由于条目的弹出(在框224中),RSB 311现在仅仅具有条目315,如第三示意图303中所示,并且RSB 311的堆栈指针被更新(如通过箭头331所指示的),作为新的条目的结果以指向下一个未使用的条目,其现在是条目322。在图3中的示意图303中示出的示例中,新的查询表312仍然包括对应于从RSB中已弹出的条目的地址(‘地址02’)的条目。在下文更加详细地描述了通过其可以将条目从新的查询表312中清除的机制。
尽管图3示出了修改的RSB 311和具有相同数量的条目的新的查询表312,这仅仅是示例的方式,并且在其它示例中,新的查询表可以具有比修改的RSB更多的条目(例如修改的RSB可以具有8个条目,而新的查询表可以具有16个条目),或者新的查询表可以具有比修改的RSB更少的条目。
如上所述,新的查询表具有有限数量的条目(例如16个条目)并且索引的大小(以及因此导致的RSB的大小)取决于查询表中的条目的最大数量。存在很多不同的机制,所述机制可以用于将条目从查询表中移除(或清除)以为待被存储的另外的地址和如图4中所示的各种示例腾出空间。这些方法可以被在图1中所示的处理器100内的取指级102内实施。
在第一示例流程图402中,当查询表是满的时候(在框421中的‘是’),使用替换算法将条目从查询表中移除(框422)。可以使用任何合适的替换算法,例如最近最少使用(LRU)算法。
在第二示例流程图403中,当误预测被识别到时(框431),使用存储的信息来恢复RSB(框432)。如上所述,该存储的信息可以包括整个RSB(例如,如在图2的框234中所存储的)或RSB的子集(例如,如在图2的框236中所存储的)。在存储的RSB数据(即来自框234的整个RSB或来自框236的RSB的子集)中没有被引用的查询表中的任何条目随后被从查询表中清除(框433)。
在第三示例流程图404中,当对应的返回指令(即框222中的返回指令,其引起图2的框224中的地址的索引从堆栈中弹出)提交时(框441),条目被从查询表中清除(在框442中)。
尽管在上文分别描述了三个示例402-404,并且可以彼此独立使用这三个示例402-404,但是在各个示例中,可以组合和一起使用这三个方法,使得在如果当数据结构是满了的时候发生函数调用时,就使用示例402,当误预测被识别到的时候,使用示例403,并且当返回指令提交时,使用示例404。在另外的示例中,可以一起使用三个示例中的任何两个示例。
在流程图402-404的以上描述中,术语“移除”和“清除”被可互换地使用以表示从查询表中去除数据,以释放条目用于存储新的地址。可替代地,代替实际移除数据,可以在查询表中使特定的条目无效并且无效的条目可以被认为是未使用的条目,其中新的地址可以被存储(例如图2中的框214中)。使用无效的地方,查询表500中的每个条目502可以具有如图5中的示意图中示出的相关联的有效位504。该有效位(其可以是一位或多位)具有一个值(例如‘1’)以指示相关联的条目是有效的,并且具有不同的值(例如‘0’)以指示相关联的条目是无效的。如果发生RSB的溢出,则也可以使用这些有效位504,如下文所述。
在使用有效位的地方,如果函数返回(例如在图2的框222中)将导致引用无效地址的索引的弹出(在框224中),则取指级102不跳转到该地址,但是相反地使用可替代的机制确定下一个地址。
如上所述,RSB仅仅包括有限数量的条目(例如8个条目),并且因此可能存在一些情况,其中索引被压入(例如在图2的框216中)到已经满了的RSB。这被称为‘溢出’。如果发生溢出,RSB可以环绕,如可以参考图6中的示意图进行描述。在第一示意图601中,RSB 600几乎是满的,在本示例中,8个条目中的7个条目是满的(如由阴影表示)。RSB的堆栈指针因此指向下一个未使用的条目611。如先前所述,为了描述的目的,堆栈被认为是向上增长的(例如,如由箭头612所指示的)。
当另一个索引被压入到RSB时,如在第二示意图602中所示,其存储在条目611中(其现在已满,并且因此在图6中以阴影示出),并且RSB的堆栈指针环绕(如通过箭头622指示),并且指向RSB中的底部条目621。该条目不是未使用的;然而,它是索引将被压入到的下一个地址。
当另外的索引被压入到RSB时,如第三示意图603中所示,它被存储在由堆栈指针识别的条目(条目621)中,对存储在该位置的先前的索引进行重写,并且堆栈指针被更新(如通过箭头632所指示)以指向用于存储索引的下一个条目(条目631)。在索引被以这种方式在RSB中重写的情况下,在查询表中对应的地址可以被清除或无效,或可替代地,地址可以保持在查询表中(例如,因为如果误预测引起引用该地址的RSB的恢复,则存在需要它的可能),并且仅当引起溢出的函数(即导致索引被压入,对先前的条目进行重写)被提交时被清除/无效。
如上所述的第一实施例导致RSB的大小的减少,其使整个RSB能够随着每次预测被存储。可替代地,还通过针对每次预测仅仅存储修改的RSB(即包括索引的RSB)的子集(连同指针,如上所述),来减少针对做出的每次预测存储的数据的量。然而,它确实导致两阶段查询过程,即,函数返回时,索引从RSB弹出,并且索引随后用于查询应当跳转到的地址(例如,如图2中的流程图202中所示)。为了减少与该两阶段过程相关联的任何延迟,对应于在RSB的顶部的索引的地址可以被提前访问(例如,在索引实际被弹出之前,并且在一些示例中,是在触发弹出的函数返回之前)。
可以参考图7-9更加详细地描述第二实施例。在本实施例中,RSB的结构被修改以包括每个条目两个(或多于两个)地址和至少一个指针位,且在图7中示出了一个示例。图7是示出了包括8个条目702的修改的RSB示例700的示意图,其中每个条目包括两个地址段704、706和一个或多个指针位708。在其它示例中,修改的RSB可以包括两个以上的地址段和附加的指针位。图7中示出了两个另外的示例710、720,并且应当理解的是,还可以使用另外的布置(例如可以组合布置700、710、720中的任何布置的方面),并且修改的RSB可以包括多于8个的条目/少于8个的条目。
在图7中示出的第二示例710中,修改的RSB(其也包括8个条目,仅仅通过示例的方式)包括三个地址段711-713,并且每个地址段具有一个或多个相关联的指针位714-716。如下文更加详细描述的,指针位714-716(和在第一示例700中的指针位708)的作用是识别条目(即当前条目)中的地址段中的一个地址段为最近写入的地址,并且还在插入当前条目时,识别先前条目中的最近添加的地址的位置。在第三示例中,其也包括三个地址段711-713,所有的指针位718在条目内组合在一起(不同于第二示例710),其中这些指针位718一起识别在该条目中的三个地址段中的一个地址段为最近写入的地址(例如通过具有值01、10或11)或指示在这三个地址段之间写入的相对顺序,并且还指示,对于(当前)条目中的每个地址段,在写入特定的段之前,直接写入在先前条目中的地址段。例如,如果段被标记为1、2、3,如果段1被写入到条目1中,并且然后段2被写入到条目2中,则与条目2相关联的指针位将识别段2为在当前条目中(条目2)中的最近写入的段,并且识别段1为在其在写入到条目2中的段2之前被直接写入的先前条目(条目1)中的段。在另外的示例中,图7中没有示出,具有每个条目两个地址段的修改的RSB可以具有每个地址段一个或多个指针位(例如通过组合示例700和710的方面)。在其它的示例中,修改的RSB可以具有每个条目多于三个地址段。
如上所述,条目的指针位提供关于其中在该条目(当前条目)中的地址段被写入的顺序的信息和关于先前的条目的信息,并且特别地,提供对于在当前条目中的每个地址段,在当前条目中的地址段被写入之前,哪个地址段被直接写入到先前的条目中的信息。当从条目中的段移除地址时,使用在先前条目上的该信息以确定返回到先前的条目中的哪个段。
图8示出了三个示例流程图801-803,其可以在图1中示出的处理器100中实现(例如通过取指级102),并且其涉及修改的RSB的操作和使用。图9示出了修改的RSB的示意图,并且仅仅为了说明的目的,修改的RSB被示出仅仅具有四个条目。应当理解的是,描述的方法可以与任何形式的修改的RSB(例如,如以上参考图7描述的)一起使用。将会从下文的描述中看到,使用修改的RSB的地方,堆栈指针具有相关联的位(本文称为堆栈指针位),其指向顶部条目(由堆栈指针所指的)中的地址段中的一个地址段。该堆栈指针位连同堆栈指针使用以知晓当预测函数返回时在什么地方从RSB进行读取(例如,堆栈指针指向最近写入的条目,指针位指向条目中的最近写入的段)。
如第一示例流程图801中所示,当函数被调用时(框812),跟随函数调用的地址被存储在修改的RSB中的下一个条目中的地址段中的一个地址段中,并且RSB的堆栈指针和堆栈指针位被更新以指向新写入的段(框814)。在RSB中的下一个条目中存在空的地址段的情况下,地址被存储在空的段中。然而,在两个地址段都已经包含地址的地方,替换算法(例如LRU)用于确定将地址存储在哪个地址段中。连同存储地址(框814中),条目中的指针位也被设置以指示在条目中最近写入的地址段和在那个时候在先前条目中的最近写入的地址(框816)。为了以下示例的目的,在每个条目中的每个段的指针位包括表示为A和B的两个部分,其中第一部分(位A)指示其是否是在条目中的最近写入的地址段(或在条目中的地址段的写入的相对顺序),并且第二部分(位B)指示了在特定的段(在当前条目中)被写入时在先前的条目中最近写入的地址段。如上所述,尽管可以组合地址段中的每个地址段的位A(例如在单个位或成对的位中以指示在当前条目中最近写入的地址段),但是不同的位B被提供给每个地址段(例如对于具有每个条目两个地址段的以下示例的位B左和位B右)。在使用时,尽管关于特定的地址段的位A的值可以改变(例如当在相同的条目中的另一个地址段被随后写入时),但是指向先前的条目的位(位B)将不改变,直到特定的地址段被重写。位B被使用使得即使在误预测之后函数返回仍工作。
图9中的示意图中示出了将条目添加到修改的RSB。在第一示意图901中,地址被添加(框814中)到第一条目912中的第一地址段911(在图9中以阴影示出存储地址的段),并且指针位913被更新(框816中)以指示(通过位A):第一段(段0)被在该条目中使用。因为这是在修改的RSB中的第一条目,在涉及该第一段和先前的条目的指针位913内的位(位B左)可以具有任何值,并且在该示例中,它具有默认值0。类似地,在涉及第二段和先前的条目的指针位913内的位(位B右)可以具有任何值,并且在该示例中它也具有默认值0。堆栈指针被更新(框814中)以指向该新添加的条目,即条目912,并且堆栈指针位被更新以指向该条目中的第一段(段0)(如通过图9中修改的RSB的左边的堆栈指针箭头所指示的)。接下来的两个示意图902-903示出了被添加到修改的RSB 900的两个另外的地址。在这两种情况下,地址被存储在它们各自的条目中的第一地址段中,并且第一指针位(位A)被设置为‘0’以指示这种情况。在这些条目中的每个条目中,第二指针位(位B左)也被设置为‘0’以指示:在这两种情况中,在先前的条目中最近添加的地址是在段0中(在本示例中位B右具有默认值0)。在每个阶段的堆栈指针由箭头示出并且指向待使用的RSB中的下一个条目,并且在图9中被绘制在修改的RSB的左边以指示指向第一段(段0)的堆栈指针位,并且被绘制在右边以指示指向第二段(段1)的堆栈指针位。与在图901-903中的每个堆栈指针相关联的堆栈指针位指向顶部条目中的第一段(段0)。
响应于函数返回(框822),如图8中的第二流程图802中所示,来自顶部条目的地址从修改的RSB中“弹出”(框824)。然而,在本实施例中,从修改的RSB中“弹出”条目不包括将其从RSB中移除,而是代之以从RSB中读取该地址(框824中)。正确的地址被读取(框824中)并且这使用堆栈指针来确定条目并使用堆栈指针位以确定哪个段。参考图9中的第三示意图903,在第一地址段931中的地址(如通过堆栈指针和堆栈指针位来指示的)被“弹出”,即被读取但是没有被移除。如第四示意图904中所示,产生的修改的RSB仍然包括在地址段931中的地址,但是堆栈指针941被更新以指向该段下方的条目(而不是该段的条目)。通过从已经“弹出的”的地址段读取适当的位B来确定新的堆栈指针位。在这种情况下,(对应于条目931的)B左是0,因此堆栈指针位被设置为0(指示第一地址段)。
响应于另外的函数返回(框822中),如第五示意图905中所示,段951中的地址被读取(框824中)但是没有被移除,并且堆栈指针952被更新以指向该段下方的条目,并且堆栈指针位被更新以指向该段中的第一条目(如被在左边的堆栈指针箭头所表示的)。
图9中的接下来的两个示意图906-907示出了将地址添加到修改的RSB的两个另外的函数调用的结果(例如使用示例流程图801)。在每种情况下,地址被存储在修改的RSB中的下一个条目中的未使用的地址段中,堆栈指针和堆栈指针位被更新,并且指针位被设置以指示在每个条目中最近写入的段(位A)和在插入时在先前条目中最近写入的段(位B右)。在图906-907中,堆栈指针位指向条目中的第二段。
下面的两个示意图908-909示出了两个函数返回的结果(例如使用示例流程图802)。由于这两个函数返回中的第一函数返回,段981中的地址被读取(如基于堆栈指针和堆栈指针位982确定的),并且堆栈指针被更新以指向该段下方的条目,其中堆栈指针位识别了该条目中的第二段(如与段981相关联的位B右被设置为1,指示了第二段)。由于两个函数返回中的第二函数返回,段991中的地址被读取(如基于指针位A 992确定的),并且堆栈指针被更新以指向包括段991的条目,其中的堆栈指针位识别了该条目中的第一段。
如图8中的第三示例流程图803中所示,当预测被做出时(框832),连同堆栈指针位存储修改的RSB的堆栈指针(框834)。如果预测被确定为是误预测,则该信息可以随后用于对RSB的堆栈指针和堆栈指针位进行复位。修改的RSB内的指针位没有被复位,而且位B在误预测之后将仍然是正确的,除非该段已经被重写(这是不可能的,因为地址被写入到不是最近添加的段)。
如上所述的第二实施例使用RSB的修改的结构,尽管可能其效率较低(因为不太可能将会使用RSB中的所有的地址段),但是却减少了由于误推测导致的数据将被丢失的可能性。当地址从RSB中“弹出”时,地址没有被移除,因此条目不会因为不正确的推测性弹出而被丢失,且后续函数调用没有导致最近写入的地址被重写。每个数据条目多个地址段的使用(例如,如图7中所示)增加了可能的低效率,但是同时减少了数据将被丢失(通过被重写)的可能性,即使在其中存在大量的推测性代码运行的情况下也是如此。
虽然以上参考了无序处理器描述了两个实施例,但是方法不限于无序处理器,并且还可以在执行有序的指令但是仍然使用推测的处理器中使用。
本文使用的术语‘处理器’和‘计算机’指的是具有处理能力使得它可以执行指令的任何设备、或其部分。例如,术语‘处理器’可以包括中央处理单元(CPU)、图形处理单元(GPU或VPU)、物理处理单元(PPU)、数字信号处理器(DSP)、通用处理器(例如通用GPU)、微处理器、被设计为对CPU外部的任务进行加速的任何处理单元等。本领域的技术人员将认识到,这样的处理能力可以并入很多不同的设备中,并且因此术语‘计算机’包括机顶盒、媒体播放器、数字收音机、PC、服务器、移动电话、个人数字助理和很多其它设备。
本领域技术人员将认识到,用于存储程序指令的存储设备可以分布在网络上。例如,远程计算机可以将描述的处理的示例存储为软件。本地或终端计算机可以访问远程计算机并且下载软件的部分或全部以运行该程序。可替代地,本地计算机可以根据需要下载软件的片段,或在本地终端执行一些软件指令和在远程计算机(或计算机网络)执行一些软件指令。本领域技术人员还将认识到,通过利用本领域技术人员已知的常规技术,通过专用电路(例如DSP、可编程逻辑阵列等类似物)可以执行软件指令的全部或部分。
用于在执行公开的方面时使用的存储机器可执行数据的储存器可以是非暂时性的介质。非暂时性的介质可以是易失性的或非易失性的。易失性的非暂时性的介质的示例包括基于半导体的储存器,例如SRAM或DRAM。可以用于实现非暂时性储存器的技术的示例包括光储存器技术和磁储存器技术、闪存、相变储存器、电阻式RAM。
对“逻辑”的特定参考指的是执行一个功能或多个功能的结构。逻辑的示例包括被布置以执行这些功能的电路。例如,这样的电路可以包括在制造过程中可用的晶体管和/或其它硬件元件。这样的晶体管和/或其它元件可以用于形成实现和/或包含储存器的电路或结构,通过示例的方式例如寄存器、触发器、或锁存器、逻辑运算符(例如布尔运算)、数学运算符(例如加法器、乘法器或移位器)和互连器。这样的元件可以被提供为定制电路或标准单元库、宏指令或在其它级别的抽象。这样的元件可以在特定的布置中互连。逻辑可以包括固定功能的电路,并且电路可以被编程以执行一个功能或多个功能;这样的编程可以从固件或软件更新或控制机制提供。被识别以执行一个功能的逻辑还可以包括执行组成的功能或子过程的逻辑。在示例中,硬件逻辑具有执行固定的功能操作或多个操作、状态机或过程的电路。
如将对技术人员明显的是,本文给定的任何范围或设备值可以扩展或改变而不失去所追求的效果。
应当理解的是,以上描述的好处和优点可以涉及一个实施例或可以涉及若干实施例。实施例不限于解决所陈述的问题中的任何或全部陈述的问题的那些实施例或具有所陈述的好处或优点中的任何或全部陈述的好处和优点的那些实施例。
对‘一个’项的任何引用指的是一个项或多个项。本文所使用的术语‘包含(comprising)’意在包括所识别的方法框或元件,但是这样的框或元件不包括排他的列表,并且装置可以包括附加的框或元件,并且方法可以包括附加的操作或元件。此外,框、元件和操作本身没有暗示是封闭的。
可以在合适的地方以任何合适的顺序执行或同时执行本文描述的方法的步骤。附图中的方框之间的箭头示出了方法步骤中的一个示例顺序,但是不旨在排除其它的顺序或并行的多个步骤的性能。此外,单独的框可以从方法中的任何方法中删除,而不脱离本文描述的主题的精神和范围。以上描述的示例中的任何描述示例的方面可以与描述的其它示例中的任何描述的其它的示例的方面组合以形成另外的示例,而不失去所追求的效果。应当理解的是,附图的元件被示出通过箭头连接的地方,这些箭头仅仅示出了元件之间的通信(包括数据和控制消息)的一个示例流动。元件之间的流动可以在任一方向或在两个方向。
应当理解的是,仅仅通过示例的方式来给出优选的实施例的以上描述,并且可以由本领域技术人员做出各种修改。尽管利用某种程度的特殊性或通过参考一个或多个单独的实施例已经在上文描述了各个实施例,但是本领域技术人员可以对公开的实施例做出许多改变而不脱离本发明的精神或范围。