具有有效的存储器访问的处理器的制作方法

文档序号:13741891阅读:179来源:国知局
具有有效的存储器访问的处理器的制作方法

发明领域

本发明大体上涉及微处理器设计,且特别是用于微处理器中的有效存储器访问的方法和系统。

发明背景

限制微处理器中的代码的并行化的主要瓶颈之一是在存储器访问指令之间的依赖性。已经提出了各种技术来改善包括存储器访问的代码的并行化性能。例如,tyson和austin在通过引用并入本文的“memoryrenaming:fast,earlyandaccurateprocessingofmemorycommunication”(internationaljournalofparallelprogramming,第27卷,第5期,1999年)中提出了被称为“存储器重命名”的技术。存储器重命名是应用寄存器访问技术来加载和存储指令以加快存储器流量的处理的处理器流水线的修改。该方法通过在流水线中早期预测存储器通信并然后将通信重新映射到快速物理寄存器来工作。

发明概述

本文描述的本发明的实施方式提供了一种方法,其包括在处理器中处理包括存储器访问指令的程序代码,其中存储器访问指令中的至少一些包括根据一个或更多个寄存器名称来指定在外部存储器中的存储器地址的符号表达式。基于在符号表达式中指定的存储器地址的相应格式来识别在由两个或更多个存储器访问指令访问的存储器地址之间的关系。基于所识别的关系来分配从处理器中的内部存储器供应的存储器访问指令中的至少一个的结果。

在一些实施方式中,识别在存储器地址之间的关系与存储器地址的实际数值无关。在实施方式中,识别在存储器地址之间的关系在存储器地址的实际数值未被定义的时间点处执行。在所公开的实施方式中,由处理器的流水线中的给定流水线级来执行识别关系,并且在位于流水线中的比给定流水线级更晚的另一流水线级中计算存储器地址的实际数值。

在一些实施方式中,识别所述关系包括在程序代码中搜索使用相同符号表达式来指定存储器地址的存储器访问指令。在实施方式中,识别关系包括在程序代码中搜索使用涉及相同存储器地址的不同的符号表达式来指定存储器地址的存储器访问指令。在另一个实施方式中,分配存储器访问指令中的至少一个的结果由处理器的流水线中的解码单元或重命名单元执行。

在一些实施方式中,分配从内部存储器供应的结果还包括在外部存储器中执行存储器访问指令,并且验证在外部存储器中执行的存储器访问指令的结果与从内部存储器分配给存储器访问指令的结果匹配。在实施方式中,验证结果包括将在外部存储器中执行的存储器访问指令的结果与从内部存储器分配给存储器访问指令的结果进行比较。在另一个实施方式中,验证结果包括验证没有介入(intervening)事件引起在外部存储器中的结果与从内部存储器分配的结果之间的不匹配。

在又一个实施方式中,验证结果包括向程序代码添加验证结果的一个或更多个指令或微操作,或将一个或更多个现有指令或微操作修改为验证结果的指令或微操作。在另一个实施方式中,该方法还包括在发现在外部存储器中执行的结果与从内部存储器供应的结果不匹配时刷新后续代码。

在一些实施方式中,该方法还包括禁止在外部存储器中执行存储器访问指令中的至少一个。在其他实施方式中,该方法还包括在多个硬件线程上的程序代码的并行执行,包括从内部存储器分配结果。在另一个实施方式中,处理程序代码包括在单个硬件线程中执行程序代码,包括从内部存储器分配结果。

在所公开的实施方式中,识别关系包括识别在循环或函数中的存储器访问指令。在另一个实施方式中,在运行时间处执行识别关系。在实施方式中,至少部分地基于嵌入在程序代码中的指示来执行识别关系。

根据本发明的实施方式,另外提供了包括内部存储器和处理电路的处理器。处理电路被配置成处理包括存储器访问指令的程序代码,其中存储器访问指令的至少一些包括根据一个或更多个寄存器名称来指定外部存储器中的存储器地址的符号表达式,以基于在符号表达式中指定的存储器地址的相应格式来识别在由两个或更多个存储器访问指令访问的存储器地址之间的关系,并基于所识别的关系来分配从内部存储器供应的存储器访问指令中的至少一个的结果。

根据结合附图进行的本发明的实施方式的以下详细描述,本发明将得到更完全地理解,其中:

附图简述

图1是根据本发明的实施方式示意性示出处理器的框图;

图2是根据本发明的实施方式示意性示出用于处理包含存储器访问指令的代码的方法的流程图;

图3是根据本发明的实施方式示意性示出用于处理包含循环加载指令的代码的方法的流程图;

图4是根据本发明的实施方式示意性示出用于处理包含加载-存储指令对的代码的方法的流程图;

图5是根据本发明的实施方式示意性示出用于处理包含具有介入数据操纵的重复的加载-存储指令对的方法的流程图;以及

图6是根据本发明的实施方式示意性示出用于从附近的存储器地址处理包含循环加载指令的代码的方法的流程图。

实施方式的详细描述

综述

本文描述的本发明的实施方式提供了用于处理包括存储器访问指令的软件代码的改善的方法和系统。在所公开的技术中,处理器监控代码指令,并找出在存储器访问指令之间的关系。关系可以包括例如访问相同存储器地址的多个加载指令、访问相同存储器地址的加载和存储指令对或者访问存储器地址的可预测模式的多个加载指令。

基于所识别的关系,处理器能够从内部存储器(例如内部寄存器、本地缓冲器)而不是从外部存储器向取决于结果的后续代码供应一些存储器访问指令的结果。在本上下文中,经由可能在处理器内部的高速缓存从外部存储器读取也被视为供应来自外部存储器的指令。

在示例实施方式中,当从相同存储器地址读取多个加载指令时,处理器在第一加载指令时读取来自该存储器地址的值,并将该值保存到内部寄存器。当处理下一个加载指令时,处理器从内部寄存器向后续代码供应值,而不等待加载指令从存储器地址中取回值。作为结果,可以更快地执行取决于加载指令的结果的后续代码,可以放宽在指令之间的依赖性,并且可以改进并行化。

通常,下一个加载指令仍在外部存储器中被执行,例如以便验证从内部存储器供应的值是否仍然有效,但执行过程不必等待它们来完成。这个特征提高了性能,因为后续代码对加载指令的依赖性被打破,并且指令并行化可以被改进。

为了识别这些关系,原则上可能等待直到由存储器访问指令访问的存储器地址的数值被解码为止,且然后识别在所解码的存储器地址的数值之间的关系。然而,这种解决方案在时延方面是昂贵的,因为由存储器访问指令访问的实际数字地址只在流水线中的后期才被知道。

相反,在本文描述的实施方式中,处理器基于指定在指令中的存储器地址的符号表达式的格式而不是基于地址的实际数值来识别在存储器访问指令之间的关系。指令一被解码,符号表达式在流水线中在早期就是可用的。作为结果,所公开的技术识别相互关联的存储器访问指令并且以小时延对相互关联的存储器访问指令起作用,从而实现快速操作和高度并行化。

本文描述了在可以被识别和利用的存储器访问指令之间的关系的若干示例。还描述了用于处理额外的内部寄存器的若干方案,例如,将微操作添加到代码的方案和修改寄存器的常规重命名的方案。

所公开的技术提供相当大的性能提高,并且适合于在多种处理器体系结构(包括多线程和单线程体系结构)中的实现。

系统描述

图1是根据本发明的实施方式示意性示出处理器20的框图。处理器20运行预编译的软件代码,同时并行化代码执行。处理器在运行时间处通过在程序指令从存储器中被取出并被处理时分析程序指令来执行指令并行化。

在本示例中,处理器20包括多个硬件线程24,其被配置为并行地进行操作。每个线程24被配置成处理代码的相应段。线程并行化的某些方面(包括部分重复的段的定义和示例)例如在美国专利申请14/578,516、14/578,518、14/583,119、14/637,418、14/673,884、14/673,889和14/690,424中被处理,这些美国专利申请全部转让给本专利申请的受让人,并且其公开内容通过引用被并入本文。

在本实施方式中,每个线程24包括取出单元28、解码单元32和重命名单元36。尽管下面给出的示例中的一些涉及指令并行化和多线程体系结构,但是所公开的技术是可应用的并且也在单线程处理器中提供相当大的性能提高。

取出模块24从存储器中(例如,从多级指令高速缓存中)取出它们的相应代码段的程序指令。在本示例中,多级指令高速缓存包括1级(l1)指令高速缓存40和2级(l2)高速缓存42,其缓存在存储器43中储存的指令。解码单元32对取出的指令进行解码(并且可能将它们转换为微操作),并且重命名单元36执行寄存器重命名。

在重命名之后的解码的指令在无序(ooo)缓冲器44中进行缓冲,用于由执行单元52进行无序(即,不按照指令被编译和存储在存储器中的顺序)执行。重命名单元将名称(物理寄存器)分配给操作数和目的寄存器,使得ooo缓冲器基于它们的操作数的可用性正确地发出(为了执行而发送)指令。可选地,缓冲的指令可以按顺序执行。

ooo缓冲器44包括寄存器文件48。在一些实施方式中,处理器还包括专用寄存器文件50,其在本文中也被称为内部存储器。寄存器文件50包括用于加速存储器访问指令的一个或更多个专用寄存器,如下面将详细解释的。

在ooo缓冲器44中缓冲的指令被调度以用于由各个执行单元52执行。指令并行化通常通过同时向各个执行单元发出多个(可能无序地)指令/微操作来实现。在本示例中,执行单元52包括被表示为alu0和alu1的两个算术逻辑单元(alu)、乘法累加(mac)单元、被表示为lsu0和lsu1的两个加载-储存单元(lsu)、分支执行单元(bru)和浮点单元(fpu)。在可选实施方式中,执行单元52可包括任何其他合适类型的执行单元和/或每种类型的任何其他合适数量的执行单元。线程24、ooo缓冲器44和执行单元52的级联结构在本文被称为处理器20的流水线。

由执行单元52产生的结果被保存在寄存器文件48和/或寄存器文件50中和/或被储存在存储器43中。在一些实施方式中,多级数据高速缓存在执行单元52和存储器43之间调解(mediate)。在本示例中,多级数据高速缓存包括1级(l1)数据高速缓存56和l2高速缓存42。

在一些实施方式中,处理器20的加载-存储单元(lsu)在执行存储指令时将数据储存在存储器43中,并在执行加载指令时从存储器系统43中取回数据。数据储存和/或取回操作可使用数据高速缓存(例如,l1高速缓存56和l2高速缓存42)来减小存储器访问延迟。在一些实施方式中,高级高速缓存(例如,l2高速缓存)可被实现为例如在相同物理存储器中的单独的存储器区域,或者在没有固定预分配的情况下仅仅共享相同的存储器。

在本上下文中,存储器43、l1高速缓存40和56以及l2高速缓存42被统称为外部存储器41。对存储器43、高速缓存40、高速缓存56或高速缓存42的任何访问都被视为对外部存储器的访问。对“在外部存储器中的地址”或“在外部存储器41中的地址”的提及指在存储器43中的数据的地址,即使可以通过读取在高速缓存56或42中的数据的缓存副本来物理地取回数据。相反,例如对寄存器文件50的访问被视为对内部存储器的访问。

分支预测单元60预测在本文中为了简洁而被称为“轨迹”的分支或流控制轨迹(在单次预测中的多个分支),其预期在执行期间由程序代码遍历。可以在单线程处理器或多线程处理器内的单线程中或者由如在上面引用的美国专利申请14/578,516、14/578,518、14/583,119、14/637,418、14/673,884、14/673,889和14/690,424中所述的各个线程24执行该代码。

基于预测,分支预测单元60指示取出单元28将从存储器中取出哪些新指令。在这个上下文中,分支预测可预测对于段或对于段的部分的整个轨迹,或预测单独分支指令的结果。当并行化代码时,例如,如在上面引用的专利申请中所描述的,状态机单元64管理各个线程24的状态,并且在适当时调用线程来执行代码段。

在一些实施方式中,处理器20并行化在线程24当中的程序代码的处理。在各种并行化任务中,处理器20使用在下面详细描述的方法来执行存储器访问指令的有效处理。并行化任务通常由处理器的各个单元执行。例如,分支预测单元60通常预测对于各个线程的控制流轨迹,状态机单元64调用线程以至少部分并行地执行适当的段,并且重命名单元36处理存储器访问并行化。在可选的实施方式中,存储器并行化单元可由解码单元32和/或联合地由解码单元32和重命名单元36执行。

因此,在本公开的上下文中和权利要求书中,单元60、64、32和36被统称为线程并行化电路(或出于简洁而仅被称为并行化电路)。在可选实施方式中,并行化电路可以包括处理器20中的单元的任何其他合适的子集。在一些实施方式中,可以使用运行时间软件来执行并行化电路的一些或甚至全部功能。这种运行时间软件通常与由处理器执行的软件代码分开,并且可以例如在单独的处理核心上运行。

在本上下文中,寄存器文件50被称为内部存储器,且术语“内部存储器”和“内部寄存器”有时可以互换使用。其余处理器元件在本文中被统称为处理电路,其使用内部存储器来执行所公开的技术。通常,其他适当类型的内部存储器也可以用于执行所公开的技术。

如已经提到的,尽管本文中描述的示例中的一些涉及多个硬件线程和线程并行化,但是许多所公开的技术可以以与单个硬件线程类似的方式来实现。处理器流水线可以包括例如单个取出单元28、单个解码单元32、单个重命名单元36,并且没有状态机64。在这样的实施方式中,所公开的技术在单线程处理中加速存储器访问。因此,尽管下面的示例涉及由并行化电路执行的存储器访问加速功能,但这些功能通常可由处理器的处理电路来执行。

图1中所示的处理器20的配置是示例配置,其纯粹为了概念清楚起见而被选择。在可选的实施方式中,可使用任何其他合适的处理器配置。例如,在图1的配置中,使用多个取出、解码和重命名单元来实现多线程。另外或可选地,多线程可以以许多其他方式实现,诸如使用每线程的多个ooo缓冲器、单独的执行单元和/或每线程的单独的寄存器文件。在另一个实施方式中,不同的线程可以包括不同的相应处理核心。

作为又一个示例,处理器可以在没有高速缓存或具有不同的高速缓存结构、在没有分支预测或者每线程有单独的分支预测的情况下实现。处理器可包括图中未示出的附加元件。此外,可选地,所公开的技术可以用具有任何其它合适的微型体系结构的处理器执行。

此外,尽管本文描述的实施方式主要涉及重复代码的并行化,但是可以使用所公开的技术来提高处理器性能,例如,用寄存器访问时间替换(和减少)存储器访问时间,减少外部存储器访问操作的数量,而不管线程并行化。这样的技术可以在单线程配置或不一定涉及线程并行化的其他配置中被应用。

处理器20可以使用任何合适的硬件来实现,诸如使用一个或更多个专用集成电路(asic)、现场可编程门阵列(fpga)或其他设备类型。另外或可选地,可使用软件或使用硬件和软件元件的组合来实现处理器20的某些元件。可以使用诸如随机访问存储器(ram)的任何合适类型的存储器来实现指令和数据高速缓存存储器。

处理器20可以用软件编程以执行本文描述的功能。软件可通过网络以电子形式下载到处理器,例如,或者可选地或另外,软件可以被提供和/或储存在非暂时性有形介质(诸如,磁存储器、光存储器或电子存储器)上。

在一些实施方式中,处理器20的并行化电路监控由一个或更多个线程24处理的代码,识别至少部分地重复的代码段,并且并行化这些代码段的执行。例如,在上面引用的美国专利申请14/578,516、14/578,518、14/583,119、14/637,418、14/673,884、14/673,889和14/690,424中处理了由并行化电路执行的并行化功能的某些方面,包括部分重复的段的定义和示例。

基于指令格式的在存储器访问指令之间的关系的早期检测

一般,由处理器20处理的程序代码包含诸如加载和存储指令的存储器访问指令。在许多情况下,代码中的不同的存储器访问指令是相互关联的,并且这些关系可以被利用来提高性能。例如,不同的存储器访问指令可以访问相同存储器地址,或者存储器地址的可预测模式。作为另一个示例,一个存储器访问指令可以读取或写入某个值,随后的指令可以以可预测的方式操作该值,并且以后的存储器访问指令然后可以将操纵值写到存储器。

在一些实施方式中,处理器20中的并行化电路识别在存储器访问指令之间的这种关系,并使用这些关系来改进并行化性能。特别是,并行化电路通过分析指定由存储器访问指令访问的地址(与地址的数值相反)的符号表达式的格式来识别关系。

通常,存储器访问指令(例如,加载或存储指令)的操作数包括符号表达式,即,根据一个或更多个寄存器名称定义的、指定待执行的存储器访问操作的表达式。存储器访问指令的符号表达式可以指定例如待访问的存储器地址、其值将被写入的寄存器或者值将被读取到其中的寄存器。

根据在处理器20中定义的指令集,符号表达式可以具有多种格式。不同的符号格式可能涉及不同的寻址模式(例如,直接寻址vs间接寻址),或者涉及索引的预递增或后递增,仅举几个例子。

在典型的流程中,解码单元32对指令(包括符号表达式)解码。然而,在这个阶段处,表达式的实际数值(例如,待访问的数字存储器地址和/或待写入的数值)还是未知的,并且可能是未定义的。就在将指令写到ooo缓冲器44之前,通过由重命名单元36评估符号表达式。只有在执行阶段处,lsu和/或alu才评估符号表达式并且给存储器访问指令分配实际数值。

在一个示例实施方式中,在lsu中评估待访问的数字存储器地址,并且在alu中评估待写入的数值。在另一个示例实施方式中,在lsu中评估待访问的数字存储器地址以及待写入的数值。

应该注意,在解码指令(使符号表达式变得可用)和评估符号表达式中的数值之间的时间延迟不仅仅是由于流水线延迟。在许多实际的情形下,给定的存储器访问指令的符号表达式不能被评估(被分配数值),直到先前指令的结果可用为止。由于这种依赖性,符号表达式可能以符号形式在它可被评估以前很久(可能是几十个循环之前)是可用的。

在一些实施方式中,并行化电路通过分析符号表达式的格式来识别和利用在存储器访问指令之间的关系。如上所解释的,可以在实际数值仍然未定义且不能被评估(例如,因为它们取决于尚未被执行的其它指令)的时间点处来识别和利用关系。由于该过程不等待待分配的实际数值,因此它可以在流水线中在早期被执行。作为结果,可以更早执行取决于存储器访问指令的结果的后续代码,可以放宽在指令之间的依赖性,并且因此可以改进并行化。

在一些实施方式中,在包含至少部分地重复的一个或更多个代码段的代码区(例如循环或函数)中应用所公开的技术。然而,通常可以使用单或多线程处理器在任何其它合适的代码区(例如,循环迭代的部分、顺序代码和/或任何其他合适的指令序列)中应用所公开的技术。

图2是根据本发明的实施方式示意性示出用于处理包含存储器访问指令的代码的方法的流程图。在监控步骤70处,方法开始于处理器20中的并行化电路监控代码指令。在符号分析步骤74处,并行化电路分析所监控的存储器访问指令的符号表达式的格式。特别是,并行化电路分析指定待访问的地址的符号表达式的部分。

在关系识别步骤78处,基于所分析的符号表达式,并行化电路识别在不同的存储器访问指令之间的关系。在供应步骤82处,基于所识别的关系,并行化电路从内部存储器(例如,处理器20的内部寄存器)而不是从外部存储器41供应存储器访问指令中的至少一些的结果。

如上面所提到的,术语“从外部存储器41供应存储器访问指令”涵盖了供应存储在存储器43中或缓存在高速缓存56或42中的值的情况。术语“从内部存储器供应存储器访问指令”指直接或间接地供应值。间接供应值的一个示例是将该值复制到内部寄存器,且然后从该内部寄存器中供应值。从内部存储器供应可以例如由相关线程24的解码单元32或重命名单元36来分配并且稍后由执行单元52中的一个来执行。

下面的描述描绘了在存储器访问指令之间的若干示例关系,并且演示处理器20如何通过识别和利用这些关系来加速存储器访问。下面的代码示例使用指令集纯粹作为示例来给出。在可选实施方式中,所公开的技术可以使用任何其他合适的指令集来执行。

示例关系:访问相同存储器地址的加载指令

在一些实施方式中,并行化电路识别从外部存储器中的相同存储器地址读取的多个加载指令(例如,ldr指令)。识别通常还包括验证没有存储指令在加载指令之间写到该相同存储器地址。

这种情形的一个示例是下列形式的加载指令:

ldrr1,[r6]

其在循环内被找到,其中r6是全局寄存器。在本上下文中,术语“全局寄存器”指在循环迭代内的各个加载之间不被写入的寄存器(即,寄存器值在循环迭代之间不改变)。上面的指令从存储器中加载驻留在被保持在r6中的地址中的值并将它放入r1中。

在该实施方式中,并行化电路分析地址“[r6]”的符号表达式的格式,识别出r6是全局的,认识符号表达式根据一个或更多个全局寄存器来定义,并且断定在各种循环迭代中的加载指令都从外部存储器中的相同地址被读取。

从相同存储器地址读取的多个加载指令不需要必须在循环内出现。考虑例如下面的代码:

ldrr1,[r5,r2]

inst

inst

inst

ldrr3,[r5,r2]

inst

inst

ldrr3,[r5,r2]

在上面示例中,所有三个加载指令都访问相同存储器地址,假设寄存器r5和r2没有在加载指令之间被写入。注意,如在上面的示例中的,各种加载指令的目的寄存器不一定是相同的。

在上面的示例中,所有识别的加载指令都使用相同符号表达式来指定地址。在可选实施方式中,并行化电路识别从相同存储器地址读取的加载指令,即使不同的加载指令可使用不同的符号表达式来指定存储器地址。例如,加载指令

ldrr1,[r6,#4]!

ldrr1,[r6]

ldrr4,[r6]

都访问相同存储器地址(在第一次加载中,寄存器r6首先通过将4加到它的值来更新)。用于访问相同存储器地址的另一个示例是重复加载指令,诸如:

ldrr1,[r6,#4]

ldrr1,[r6,r4](其中r4也不变)

ldrr1,[r6,r4lsl#2]

并行化电路可以认识到,这些符号表达式都以各种方式例如通过保持指定相同地址的符号表达式的等效格式的预定列表来指代相同地址。

当识别出这样的关系时,并行化电路通过内部寄存器中的加载指令之一将从外部存储器读取的值保存在例如寄存器文件50中的专用寄存器之一中。例如,处理器并行化电路可以保存在第一循环迭代中由加载指令读取的值。当执行后续加载指令时,并行化电路可以从内部存储器供应加载指令的结果,而不等待值从外部存储器被取回。该值可以从内部存储器供应到取决于该值的后续代码指令。

在可选实施方式中,并行化电路可以不仅在循环中而且在函数中、在循环迭代的部分中、在顺序代码中和/或在任何其它合适的指令序列中识别递归(recurring)加载指令。

在各种实施方式中,处理器20可以以各种方式实现上述机制。在一个实施方式中,并行化电路(通常是相关线程的解码单元32或重命名单元36)通过向代码添加指令或微操作来实现该机制。

例如,考虑包含(在其他指令当中)三条指令的循环

ldrr1,[r6]

addr7,r6,r1

movr1,r8

其中,r6是该循环中的全局寄存器。在本示例中的第一条指令将值从存储器加载到r1中,以及第二条指令将r6和r1的值相加并将它放入r7中。注意,第二条指令取决于第一条指令。进一步注意,从存储器加载的值在将r8的值分配给r1的第三条指令中“丢失”,且因此在每次迭代中需要从存储器中重新加载它。在实施方式中,在第一循环迭代中的ldr指令之后,在识别出在递归的idr指令之间的关系时,并行化电路添加下列格式的指令:

movmsg,r1

其中msg表示专用内部寄存器。该指令在附加寄存器中分配从存储器中加载的值。第一循环迭代因此变成:

ldrr1,[r6]

movmsg,r1

addr7,r6,r1

movr1,r8

作为结果,在执行第一循环迭代时,将从外部存储器中读取由“[r6]”指定的地址,并将读取的值保存到寄存器msg中。

在随后的循环迭代中,并行化电路添加下列格式的指令:

movr1,msg

其在ldr指令之后将在附加寄存器中保存的值分配给r1。随后的循环迭代因此变成:

ldrr1,[r6]

movr1,msg

addr7,r6,r1

movr8,r1

作为结果,当执行后续循环迭代时,寄存器msg的值将被加载到寄存器r1中,而不必等待ldr指令从外部存储器41取回值。

由于mov指令是alu指令且不涉及访问外部存储器,因此它比ldr指令(通常是单个周期而不是四个周期)快得多。而且,add指令不再取决于ldr指令,而只取决于mov指令,且因此后续代码从处理时间的减少中受益。

在可选实施方式中,并行化电路实现上述机制而不将指令或微操作添加到代码,而是通过配置寄存器在重命名单元36中被重新命名的方式。考虑上面的示例或者包含(在其他指令之中)三条指令的循环:

ldrr1,[r6]

addr7,r6,r1

movr1,r8

当在第一循环迭代中处理ldr指令时,重命名单元36执行常规重命名,即,将目的寄存器r1重命名为某个物理寄存器(在本示例中被表示为p8),并且从p8中供应在add指令中的操作数r1。当处理mov指令时,r1被重命名为新的物理寄存器(例如,p9)。与常规重命名不同,当p9被提交时,p8不会被释放。处理器因此保持寄存器p8的值,该寄存器p8保存从存储器加载的值。

另一方面,当执行后续循环迭代时,重命名单元36应用不同的重命名方案。所有后续循环迭代的add指令中的操作数r1都从相同物理寄存器p8中读取值,消除了等待加载指令的结果的需要。寄存器p8仅在最后一次循环迭代后才被释放。

进一步可选地,并行化电路可以以任何其他合适的方式来从内部寄存器供应读取的值。通常,内部寄存器仅专用于此目的。例如,内部寄存器可以包括在寄存器文件48中的处理器的架构寄存器之一,其不暴露于用户。可选地,内部寄存器可以包括寄存器文件50中的寄存器,其不是寄存器文件48(如r6)或物理寄存器(如p8)中的处理器的架构寄存器之一。作为对将值保存在处理器的内部寄存器中的可选方案,处理器的任何其他合适的内部存储器也可用于此目的。

从内部寄存器(例如msg或p8)而不是从外部存储器地址的实际内容供应ldr指令的结果涉及小但不可忽略的错误概率。例如,如果在第一个加载指令之后的任何时间处将不同的值写到所讨论的存储器地址,那么实际读取的值将与保存在内部寄存器中的值不同。作为另一个示例,如果寄存器r6的值被改变(即使它被假设是全局的),则下一个加载指令将从不同的存储器地址被读取。在这种情况下,实际读取的值也将与保存在内部寄存器中的值不同。

因此,在一些实施方式中,在从内部寄存器供应加载指令的结果之后,并行化电路验证所供应的值确实匹配由加载指令从外部存储器41取回的实际值。如果发现不匹配,则并行化电路可以刷新后续指令和结果。刷新通常包括丢弃来自流水线的所有后续指令,使得用错误的操作数值执行的所有处理都被丢弃。换句话说,为了验证的目的,处理器执行外部存储器中的后续加载指令并从所讨论的存储器地址中取回值,即使该值是从内部寄存器供应的。

例如,可以通过验证在递归加载指令之间没有存储(例如,str)指令写到存储器地址来执行上述验证。另外或可选地,验证可以确定没有围栏指令(fenceinstructions)限制从内部存储器供应后续代码的可能性。

然而,在一些情况下,可能由另一实体(例如,由另一个处理器或处理器核心)或由调试器写到所讨论的存储器地址。在这种情况下,验证被监控的程序代码不包含被写到存储器地址的介入存储指令可能是不够的。在实施方式中,验证可以使用来自存储器管理子系统的指示,指示存储器地址的内容是否被修改。

在本上下文中,介入存储指令、介入围栏指令和/或来自存储器管理子系统的指示都被视为介入事件,其造成外部存储器中的值与从内部存储器供应的值之间的不匹配。验证过程可以考虑这些事件中的任何一个和/或任何其他合适的介入事件。

在又一些其他实施方式中,并行化电路可以最初假定没有介入事件影响所讨论的存储器地址。如果在执行期间某个验证机制失败,则并行化电路可以推断出介入事件可能存在,并且抑制从内部存储器供应结果。

作为另一个示例,并行化电路(通常为解码单元32或重命名单元36)可以向代码添加从外部存储器中取回正确值的指令或微操作并将它与内部寄存器的值进行比较。实际比较可以例如由执行单元52中的alu或lsu之一来执行。注意,没有指令取决于所添加的微操作,因为它不存在于原始代码中且仅用于验证。进一步可选地,并行化电路可以以任何其他合适的方式执行验证。注意,此验证当它是正确的时不影响通过快速加载到寄存器r1而得到的性能益处,而是在它是错误的情况下刷新此快速加载。

图3是根据本发明的实施方式示意性示出用于处理包含递归加载指令的代码的方法的流程图。在递归加载识别步骤90处,该方法开始于处理器20的并行化电路识别访问相同存储器地址(无介入事件)的递归的多个加载指令。

如上面所解释的,该识别基于加载指令的符号表达式的格式而不是基于存储器地址的数值来进行。识别还可以考虑和利用诸如程序代码中的加载指令的程序计数器(pc)值、程序地址、指令索引和地址操作数的因素。

在加载执行步骤94处,处理器20调度下一个加载指令以在外部存储器41中执行。在第一次出现检查步骤98处,并行化电路检查刚刚执行的加载指令是否是在递归加载指令中第一次出现。

在第一次出现时,在保存步骤102处,并行化电路将从外部存储器读取的值保存在内部寄存器中。在供应步骤106处,并行化电路将该值供应给后续代码。在迭代递增步骤110处,并行化电路然后继续进行到递归加载指令中的下一次出现。然后该方法循环回到步骤94,用于执行下一个加载指令。(为了清楚起见,代码中的其他指令从此流程被省略)。

在来自相同地址的加载指令的随后出现时,在内部供应步骤114处,并行化电路从内部寄存器供应加载指令的结果(或者更确切地说,分配待供应的结果)。注意,尽管步骤114在流程图中出现在步骤94之后,但与步骤114有关的实际执行在与步骤94有关的执行之前结束。

在验证步骤118处,并行化电路验证所供应的值(在步骤102处保存在内部寄存器中的值)是否等于从外部存储器取回的值(在本次迭代的步骤94处取回)。如果是,则该方法继续进行到步骤110。如果发现不匹配,则并行化电路在刷新步骤122处刷新随后的指令和/或结果。

在一些实施方式中,递归加载指令都在具有相同流控制的相应代码段中重现。例如,如果循环不包含任何条件分支指令,则所有循环迭代(包括加载指令)将遍历相同流控制轨迹。另一方面,如果循环确实包含一个或更多个条件分支指令,则不同的循环迭代可以遍历不同的流控制轨迹。在这种情况下,递归加载指令可能不一定在所有可能的轨迹中重现。

在一些实施方式中,并行化电路从内部寄存器将递归加载指令的结果只供应给与和初始加载指令(其结果保存在内部寄存器中)相同的流控制轨迹相关联的后续代码。在这种情况下,并行化电路所考虑的轨迹可以是由代码遍历的实际轨迹,或者预期将被遍历的预测轨迹。在后一种情况下,如果预测失败,则后续代码可被刷新。在可选实施方式中,并行化电路将来自内部寄存器的递归加载指令的结果供应给后续代码,而不管它是否与相同的轨迹相关联。

为了清楚起见,以上描述涉及从相同存储器地址读取的单组读指令。在一些实施方式中,并行化电路可以处理两组或更多组的递归读指令,每个读指令从相应的公共地址被读取。可以在包含至少部分地重复的段的代码的相同区中识别和处理这样的组。例如,并行化电路可以为此目的处理多个专用寄存器(像上面描述的msg寄存器一样)。

在一些情况下,递归加载指令位于循环迭代的末尾处或附近,并且取决于读取的值的后续代码位于循环迭代的开始处或附近。在这种情况下,并行化电路可以将在一次循环迭代中获得的值供应给随后的循环迭代。值最初被读取的迭代以及向其供应该值的迭代可以由不同的线程24或由相同线程处理。

在一些实施方式中,即使在使用存储在存储器中的指针值间接地指定地址时,并行化电路也能够识别出从相同地址读取的多个加载指令。考虑例如代码:

ldrr3,[r4]

ldrr1,[r3,#4]

addr8,r1,r4

movr3,r7

movr1,r9

其中,r4是全局的。在这个示例中,地址[r4]拥有一个指针。然而,对r1(和r3)的所有加载的值在所有迭代中是相同的。

在一些实施方式中,并行化电路将与递归加载指令有关的信息保存为通过监控代码的相关区而产生的数据结构(被称为“记分板”)的一部分。例如,在上面引用的美国专利申请14/578,516、14/578,518、14/583,119、14/637,418、14/673,884、14/673,889和14/690,424中处理监控和记分板构造和使用的某些方面。在这样的记分板中,并行化电路可以保存例如地址格式或pc值。每当到达这个代码区时,并行化电路(例如重命名单元)可以从记分板取回信息并添加微操作或相应地改变重命名方案。

示例关系:访问相同存储器地址的加载-存储指令对

在一些实施方式中,并行化电路基于符号表达式的格式来识别存储指令和随后的加载指令,其均访问外部存储器中的相同存储器地址。这样的一对在本文中被称为“加载-存储对”。并行化电路将由存储指令存储的值保存在内部寄存器中,并且从内部寄存器供应(或者至少分配以用于供应)加载指令的结果,而不等待从外部存储器41取回该值。该值可以从内部寄存器供应给取决于在该对中的加载指令的结果的任何后续代码指令。内部寄存器可以包括例如在寄存器文件50中的专用寄存器之一。

加载-存储对的识别以及是否从内部寄存器供应结果的决定可以例如由相关的解码单元32或重命名单元36执行。

在一些实施方式中,加载指令和存储指令都使用例如在下列代码中的相同的符号格式来指定地址:

strr1,[r2]

inst

inst

inst

ldrr8,[r2]

在其他实施方式中,加载指令和存储指令使用不同的符号格式来指定地址,该不同的符号格式然而指向相同存储器地址。这样的加载-存储对可以包括例如:

strr1,[r2,#4]!和ldrr8,[r2],

strr1,[r2],#4和ldrr8,[r2,#-4]

在第一个示例(strr1,[r2,#4]!)中,在计算存储地址之前,r2的值被更新为增加4。因此,存储和加载指向相同地址。在第二个例子(strr1,[r2],#4)中,在计算存储地址之后,r2的值被更新为增加4,而然后根据r2减去4的新值计算加载地址。因此,在这个示例中,存储和加载也指向相同地址。

在一些实施方式中,给定加载-存储对的存储和加载指令由相同硬件线程24处理。在可选实施方式中,给定加载-存储对的存储和加载指令可以由不同的硬件线程处理。

如上面关于递归加载指令所解释的,在加载-存储对的情况下,并行化电路可以通过向代码添加指令或微操作来从内部寄存器供应加载指令的结果。该指令或微操作可以被添加在代码中的任何合适的位置处,其中对于存储指令的数据被准备好(不一定在存储指令之后——可能在存储指令之前)。添加指令或微操作可以例如由相关的解码单元32或重命名单元36执行。

考虑例如下面的代码:

strr8,[r6]

inst

inst

inst

ldrr1,[r6],#1

并行化电路可以添加微操作:

movmsgl,r8

其在其中r8的值可用的合适位置处将r8的值分配给另一个寄存器(其被称为msgl)。在ldr指令之后,并行化电路可以添加微操作:

movr1,msgl

其将msgl的值分配到寄存器r1中。

可选地,并行化电路可以通过配置重命名方案来从内部寄存器供应加载指令的结果,使得结果从由存储指令映射的相同物理寄存器被供应。该操作也可以在其中对于存储指令的数据已经被分配给最后一个物理寄存器(例如,一旦分配给r8值的微操作已经通过重命名单元)的任何适合的时间处执行。例如,重命名单元36可以将由存储指令存储的值分配给某个物理寄存器,并且将取决于相应的加载指令的结果的指令重命名以从该物理寄存器接收结果。

在实施方式中,并行化电路验证参与存储指令中的地址的符号表达式的寄存器在该对的存储指令与加载指令之间未被更新。

在实施方式中,存储指令存储某个宽度的字(例如,32位字),并且相应的加载指令加载被包含在所存储的字内的不同宽度(例如8位字节)的字。例如,存储指令可以将32位字存储在某个地址中,并且该对中的加载指令可以加载在32位字中的某个8位字节。这种情况也被视为访问相同存储器地址的加载-存储对。

为了作为(qualifyas)加载-存储对,在存储和加载指令中的地址的符号表达式不需要必须使用相同的寄存器。例如,并行化电路可以将存储指令和加载指令配对在一起,即使它们的符号表达式使用不同的寄存器但已知具有相同的值。

在一些实施方式中,在存储和加载指令中的地址的符号表达式中的寄存器是索引,即,它们的值以某个步幅(stride)或其他固定计算递增,以便对外部存储器中的阵列寻址。例如,加载指令和对应的存储指令可以定位在循环内,使得每一对访问以逐渐增长的方式递增的存储器地址。

在一些实施方式中,并行化电路在从内部寄存器供应加载-存储对中的加载指令的结果时验证所供应的值确实与由加载指令从外部存储器41取回的实际值相匹配。如果发现不匹配,则并行化电路可以刷新后续的指令和结果。

任何合适的验证方案都能够用于该目的。例如,如上面关于递归加载指令所解释的,并行化电路(例如重命名单元)可以添加执行验证的指令或微操作。实际的比较可以由alu或可选地在lsu中执行。可选地,并行化电路可以验证出现在存储指令中的地址的符号表达式中的寄存器在存储指令和相应的加载指令之间未被写入。进一步可选地,如上面所解释的,并行化电路可以检查各种其他介入事件(例如围栏指令或由其他实体进行的存储器访问)。

在一些实施方式中,并行化单元可以禁止在外部存储器中执行加载指令。在实施方式中,不是禁止加载指令,而是并行化电路(例如重命名单元)将加载指令修改为执行上述验证的指令或微操作。

在一些实施方式中,并行化电路从内部寄存器将加载-存储对中的加载指令的结果只供应给与一个或多个特定流控制轨迹关联的后续代码,其中加载-存储对被识别出。对于可能不包括所讨论的加载-存储对的其他轨迹,并行化电路可以在外部存储器中常规地执行加载指令。

在这个上下文中,并行化电路所考虑的轨迹可以是由代码遍历的实际轨迹,或者预期将被遍历的预测轨迹。在后一种情况下,如果预测失败,则后续代码可被刷新。在可选实施方式中,并行化电路从内部寄存器将加载指令的结果供应给与任何流控制轨迹关联的后续代码。

在一些实施方式中,在该对中的存储或加载指令的识别和用于插入微操作的位置也可以基于诸如在程序代码中的加载和存储指令的程序计数器(pc)值、程序地址、指令索引和地址操作数的因素。例如,当在循环中识别加载-存储对时,并行化电路可以保存加载指令的pc值。每当处理器遍历这个pc时,这个信息就向并行化电路指示确切地在哪里插入附加的微操作。

图4是根据本发明的实施方式示意性示出用于处理包含加载-存储指令对的代码的方法的流程图。在对识别步骤130处,该方法开始于并行化电路识别基于地址格式访问相同存储器地址的一个或更多个加载-存储对。

对于给定对,在内部保存步骤134处,并行化电路将由存储指令存储(或将要存储)的值保存在内部寄存器中。在内部供应步骤138处,并行化电路不等待该对中的加载指令从外部存储器取回该值。相反,并行化电路从内部寄存器将加载指令的结果供应给取决于该值的任何后续指令。

上面的示例涉及在代码的给定重复区(例如循环)中的单个加载-存储对。然而,通常并行化电路可以识别并处理在相同代码区中的两个或更多个不同的加载-存储对。而且,多个加载指令可以与同一存储指令配对。并行化电路可以将这种情形视为多个加载存储对,但是将所存储的值分配给内部寄存器仅仅一次。

如上面关于递归加载指令所解释的,并行化电路可以将关于加载-存储对的识别的信息存储在与所讨论的代码区有关的记分板中。在可选实施方式中,当添加mov微操作时,重命名单元可以使用被存储的寄存器的物理名称作为待加载的寄存器的操作数。

示例关系:具有存储的值的可预测操纵的加载-存储指令对

如上面所解释的,在一些实施方式中,并行化电路识别包含至少部分地重复的一个或更多个代码段的代码区,其中该区中的代码包括重复的加载-存储对。在一些实施方式中,并行化电路进一步识别出从外部存储器加载的值使用在连续迭代的加载指令之间(或类似地,在给定迭代中的加载指令和随后的存储指令之间)的一些可预测的计算来操纵。

这些识别例如由相关的解码单元32或重命名单元36基于指令的符号表达式的格式来执行。如下面将要解释的,重复的加载-存储对不需要必须访问相同存储器地址。

在一些实施方式中,并行化电路将所加载的值保存在内部寄存器或其他内部存储器中,并使用相同的可预测计算来操作该值。然后操纵值被分配以供应给取决于下一个加载指令的结果的后续代码,而不必等待实际加载指令从外部存储器中取回值。

例如,考虑包含以下代码的循环:

其中,r6是全局寄存器。指令e-g使存储在存储器地址“[r6]”中的计数器值递增。指令a和b利用在前一个循环迭代中设置的计数器值。在加载指令和存储指令之间,程序代码通过一些可预测操纵(在本示例中,在指令f中递增1)来操纵读取的值。

在本示例中,指令a取决于在前一次迭代中由指令g存储到“[r6]”中的值。在一些实施方式中,并行化电路将从内部寄存器(或其他内部存储器)分配待供应的加载指令(指令a)的结果给后续代码,而不等待从外部存储器取回该值。并行化电路对内部寄存器执行相同的可预测操纵,使得供应的值将是正确的。当使用这种技术时,指令a仍然取决于在前一次迭代中的指令g,但是取决于由指令a读取的值的指令可以在早些时候被处理。

在一个实施方式中,在第一循环迭代中,并行化电路添加微操作:

movmsi,r1

在指令a之后,或

movmsi,r8

在指令e之后并且在指令f之前,其中msi表示内部寄存器,诸如在寄存器文件50中的专用寄存器之一。在随后的循环迭代中,并行化电路在迭代开始时或者在希望利用msi之前的循环迭代中的任何其它合适的位置处添加微操作:

msi,msi,#1。

这个微操作使内部寄存器msi递增1,即执行在前一次迭代中的指令f的相同的可预测操纵。另外,(在第一个增量微操作被插入之后)在访问“[r6]”的每条加载指令之后(在本示例中的指令a和e之后,注意,在指令e之后,微操作r8,msi将被添加),并行化电路添加微操作:

movr1,msi。

作为结果,取决于这些加载指令的任何指令都将从内部寄存器msi而不是从外部存储器供应。例如,以上添加指令或微操作可以通过相关的解码单元32或重命名单元36来执行。

在上面的示例中,并行化电路在每次迭代中执行一次可预测操纵,以便为下一次迭代的代码供应正确的值。在可选实施方式中,并行化电路可以在给定的迭代中多次执行可预测操纵,并且将不同的预测值供应给不同的后续迭代的代码。在上面的计数递增示例中,在第一次迭代中,并行化电路可以计算计数器的接下来的n个值,并且为每个迭代的代码提供正确的计数器值。可以在不等待加载指令从外部存储器取回计数器值的情况下执行这些操作中的任何一个。这个提前计算可以每n次迭代重复。

在可选实施方式中,在第一次迭代中,并行化电路将目的寄存器r1(在指令a中)重命名为被表示为p8的物理寄存器。然后并行化电路添加一个或更多个微操作或指令(或修改现有的微操作,例如指令a)以计算nr8、r8、#1值的向量。该向量被保存在专用寄存器m1...mn的集合中,例如在寄存器文件50中。在随后的迭代中,并行化电路重命名添加指令(指令d)的操作数以从各个寄存器m1...mn(根据迭代次数)被读取。并行化电路可以包括用于在少量周期中执行这些向量的合适的向量处理硬件。

图5是根据本发明的实施方式示意性示出用于处理包含具有介入数据操纵的重复的加载-存储指令对的方法的流程图。在识别步骤140处,该方法开始于并行化电路识别包含具有介入数据操纵的重复的加载-存储对的代码区。并行化电路分析代码,以便识别加载-存储对和数据操纵。数据操纵通常包括由alu或者由另一执行单元(诸如fpu或mac单元)执行的操作。通常,尽管不一定,操纵通过单个指令来执行。

例如,当所讨论的代码区是程序循环时,每个加载-存储对通常包括在给定的循环迭代中的存储指令和在从相同存储器地址读取的、在下一次迭代中的加载指令。

对于给定的加载-存储对,在内部保存步骤144处,并行化电路分配在内部寄存器中通过第一加载指令加载的值。在操纵步骤148处,并行化电路对内部寄存器应用(在步骤140处识别的)相同的数据操纵。例如,可以使用alu、fpu或mac单元来应用该操纵。

在内部供应步骤152处,并行化电路不等待下一个加载指令从外部存储器取回操纵值。相反,并行化电路从内部寄存器中将(在步骤148处计算的)操纵值分配给取决于下一个加载指令的任何后续指令。

在上面的示例中,计数器值总是存储在相同存储器地址(“[r6]”中,其中r6是全局寄存器)(并从相同存储器地址取回)。但是,这个条件并不是强制性的。例如,每次迭代可以将计数器值存储在外部存储器41中的不同(例如,逐渐增加的)地址中。换句话说,在给定的迭代中,该值可以从给定地址被加载、操纵且然后存储在不同的地址中。关系仍然存在于由不同迭代的加载和存储指令访问的存储器地址之间:在给定迭代中的加载指令访问与前一次迭代的存储指令相同的地址。

在实施方式中,存储指令存储某个宽度的字(例如32位字),并且相应的加载指令加载被包含在所存储的字内的不同宽度(例如8位字节)的字。例如,存储指令可以将32位字存储在某个地址中,并且该对中的加载指令可以加载在32位字中的某个8位字节。这种情形也被视为访问相同存储器地址的加载-存储对。在这样的实施方式中,可预测操纵应该被应用到由加载指令加载的较小尺寸的字。

如在前面的示例中的,并行化电路一般在从内部寄存器供应操纵值时验证供应的值确实与通过加载指令和操纵取回之后的实际值匹配。如果发现不匹配,则并行化电路可以刷新后续的指令和结果。任何合适的验证方案都可以用于此目的,例如通过添加一个或更多个指令或微操作,或者通过验证存储指令中的地址在存储指令和相应的加载指令之间没有被写入。

进一步可选地,如上面所解释的,并行化电路可以检查各种其他介入事件(例如围栏指令,或由其他实体进行的存储器访问)。

例如,可以通过重命名单元来执行指令或微操作的添加。在供应的值与实际值之间的实际比较可以由alu或lsu执行。

在一些实施方式中,并行化单元可以禁止在外部存储器中执行加载指令。在实施方式中,不是禁止加载指令,并行化电路(例如重命名单元)将加载指令修改为执行上述验证的指令或微操作。

在一些实施方式中,例如只有当后续加载-存储对与和当前对相同的流控制轨迹相关联时,并行化电路才将来自内部寄存器的操纵值只供应给与特定流控制轨迹或轨迹组相关联的后续代码。在这个上下文中,并行化电路所考虑的轨迹可以是由代码遍历的实际轨迹,或者预期将被遍历的预测轨迹。在后一种情况下,如果预测失败,则后续代码可被刷新。在可选实施方式中,并行化电路将来自内部寄存器的操纵值供应给与任何流控制轨迹相关联的后续代码。

在一些实施方式中,从内部寄存器供应操纵值的决定和/或在用于添加或操纵微操作的代码中的位置的识别也可以考虑诸如在程序代码中的加载和存储指令的程序计数器(pc)值、程序地址、指令索引和地址操作数。可以例如由相关的重命名或解码单元来执行从内部寄存器供应操纵值的决定和/或操纵值应该被供应到的代码的识别。

上面的示例是指在给定代码区(例如循环)中的单个可预测操纵和重复的加载-存储对的单个序列。然而,通常并行化电路可以在相同代码区中识别和处理两个或更多个不同的可预测操纵和/或重复的加载-存储对的两个或更多个序列。此外,如上所述,多个加载指令可以与相同的存储指令配对。并行化电路可以将这种情形考虑为多个加载-存储对,其中所存储的值被分配给内部寄存器仅仅一次。

如上面所解释的,并行化电路可以将有关加载-储存对的识别的信息和可预测操纵存储在与所讨论的代码区相关的记分板中。

示例关系:访问附近存储器地址的模式的递归加载指令

在一些实施方式中,并行化电路识别程序代码的区,其包括访问在外部存储器41中的不同但是附近的存储器地址的加载指令的重复序列。例如,在从存储在外部存储器中的向量或其他阵列中读取值的程序循环中、在访问堆栈时或者在图像处理或过滤应用中出现这样的情形。

在一个实施方式中,序列中的加载指令例如在读取存储在外部存储器中的向量的相应元素的循环中访问递增的相邻存储器地址。在另一个实施方式中,在序列中的加载指令访问不相邻但彼此相差一个恒定偏移量(有时被称为“步幅”)的地址。例如,在读取阵列的特定列的循环中出现这种情况。

进一步可选地,在序列中的加载指令可以访问根据任何其他合适的可预测模式递增或递减的地址。通常,虽然不一定,模式是周期性的。当读取在存储器中存储的阵列(例如矩阵)的两列或更多列时,出现比步幅更复杂的周期性模式的另一个示例。

上面的示例指程序循环。然而,通常并行化电路可以识别包括这样的重复加载指令的任何其它代码区,例如在循环迭代的部分、顺序代码和/或任何其它合适的指令序列中。

并行化电路基于指定加载指令中的地址的符号表达式的格式来识别重复加载指令的序列以及从中读取地址的可预测模式。因此,在流水线中在早期例如由相关的解码单元或重命名单元执行识别。

在识别出由加载指令序列访问的地址的可预测模式之后,并行化电路可以在后续的读指令被处理之前响应于序列中的给定读指令而访问多个地址。在一些实施方式中,响应于给定读指令,并行化电路使用所识别的模式来将序列中的多个未来地址读取到内部寄存器(或其他内部存储器)中。并行化电路然后可以将来自内部存储器的读取的值中的任一个分配给取决于相应的读指令的一个或更多个将来的指令,而不等待该读指令从外部存储器读取值。

在一些实施方式中,由lsu执行的基本读操作从存储器43中的连续地址块(可能经由高速缓存56或42)读取多个数据值。该多个数据值有时被称为“缓存行”。缓存行可以包括例如六十四个字节,并且单个数据值可以包括例如四或八个字节,但是可以使用任何其他合适的缓存行大小。通常,即使被请求从单个地址读取单个数据值,lsu或高速缓存也读取整个缓存行,而不管所请求的值的实际数量。

在一些实施方式中,lsu或高速缓存响应于在上述序列中的给定读指令来读取缓存行。根据地址的模式,缓存行还可以包含一个或更多个数据值,这些数据值将被序列中的一个或更多个后续读指令(除了由给定读指令所请求的数据值之外)访问。在实施方式中,并行化电路基于地址的模式从缓存行中提取多个数据值,将它们保存在内部寄存器中,并将它们供应给适当的未来指令。

因此,在本上下文中,术语“附近地址”意指相对于缓存行大小彼此接近的地址。例如,如果每个缓存行包括n个数据值,则并行化电路可以在该序列中的每n个读指令重复上述过程。

此外,如果并行化电路、lsu或高速缓存识别出为了从存储器加载n个数据值,需要获得另一个缓存行,则它可以发起从相关缓存行的存储器的读取。可选地,不是将下一个缓存行读取到lsu中,而是能够基于识别和模式来设置预取触发器,用于将数据读取到l1高速缓存56。

当单个缓存行包括将由该序列中的未来读指令请求的许多数据值时(例如,当单个缓存行包括该模式的多个周期时),该技术是特别有效的。当序列中的读指令以大的间隔到达执行单元52时,例如当它们被许多其他指令分开时,性能益处也是相当大的。

图6是根据本发明的实施方式示意性示出用于处理包含来自附近存储器地址的递归加载指令的代码的方法的流程图。该方法在序列识别步骤160处开始于并行化电路根据可预测模式来识别访问存储器43中的各个存储器地址的读指令的重复序列。

在缓存行读出步骤164处,响应于在序列中的给定读指令,执行单元52(或高速缓存)中的lsu从存储器43(可能经由高速缓存56或42)读取一个或若干个缓存行。在提取步骤168处,并行化电路从缓存行提取由给定读指令所请求的数据值。另外,并行化电路使用地址的所识别的模式来从缓存行提取一个或更多个数据值,这些数据值将由序列中的一个或更多个后续读指令请求。例如,如果模式指示读指令从某个基地址开始访问每第四个地址,则并行化电路可以从缓存行中提取每第四个数据值。

作为内部储存步骤168,并行化电路将所提取的数据值保存在内部存储器中。所提取的数据值可以被保存在例如寄存器文件50中的内部寄存器的集合中。缓存行中的其他数据可被丢弃。在其他实施方式中,并行化电路可以将整个缓存行复制到内部存储器,并且稍后根据该模式从内部存储器分配适当的值。

在供应步骤172处,并行化电路将来自内部寄存器的数据值供应给取决于它们的后续代码指令。例如,第k个提取的数据值可以被供应给取决于在给定读指令之后的第k个读指令的结果的任何指令。可以从内部存储器供应第k个提取的数据值,而不等待第k个读指令从外部存储器取回数据值。

例如,考虑包含以下代码的循环:

ldrr1,[r6],#4

addr7,r6,r1

其中,r6是全局寄存器。该循环从在循环开始时初始化的某个基地址开始从每第四个地址读取数据值。如上面所解释的,并行化电路可以识别包含该循环的代码区,识别可预测的地址模式,然后从所取回的缓存行中提取并供应多个数据值。

在一些实施方式中,通过向代码添加一个或更多个指令或微操作或者例如由相关的重命名单元36修改现有的一个或更多个指令或微操作来实现该机制。

参考上面的示例,在实施方式中,在第一循环迭代中,并行化电路将负载(ldr)指令修改为

vec_ldrma,r1

其中,ma表示例如在寄存器文件50中的内部寄存器的集合。

在随后的循环迭代中,并行化电路在ldr指令之后添加以下指令:

movr1,ma(iteration_number)

在第一次循环迭代中的vec_ldr指令将多个所取回的值保存到ma寄存器中,且在后续迭代中的mov指令将来自ma寄存器的值分配给寄存器r1,而与ldr指令没有直接的关系。这允许在不等待ldr指令完成的情况下发出/执行后续的add指令。

在可选实施方式中,并行化电路(例如重命名单元36)通过重命名方案的适当设置来实现上述机制。参考上面的示例,在实施方式中,在第一次循环迭代中,并行化电路将负载(ldr)指令修改为

vec_ldrma,r1

在后续的循环迭代中,即使新的ldr目标被重命名为不同的物理寄存器,并行化电路也将add指令的操作数重命名为从ma(iteration_num)读取。另外,并行化电路不以常规方式(即,在下一次对r1的写入被提交时)释放ma寄存器的映射。相反,映射被保持,直到从当前缓存行中提取的所有数据值都被供应为止

在上面的两个示例中,并行化电路可以使用一系列的ldr微操作而不是ldr_vec指令。

对于给定的地址模式,每个缓存行包含给定数量的数据值。如果循环迭代的次数大于每缓存行的数据值的数量,或者如果加载之一跨越缓存行边界(例如,因为负载不一定与缓存行的起点对齐),那么在当前缓存行被耗尽时应该读取新的缓存行。在一些实施方式中,并行化电路自动指示lsu读取下一个缓存行。

访问可预测的附近地址模式的重复加载指令的其他非限制性示例可以包括:

ldrr2,[r5,r1],其中r1是索引

ldrr2,[r1,#4]!

ldrr2,[r1],#4

ldrr3,[r8,sl,lsl#2],其中sl是索引

或展开的循环的示例:

ldrr1,[r5,#4]

ldrr1,[r5,#8]

ldrr1,[r5,#12]

...

在一些实施方式中,序列中的所有加载指令都由相同硬件线程24处理(例如,当处理展开的循环时,或者当处理器是单线程处理器时)。在可选实施方式中,序列中的加载指令可以由至少两个不同的硬件线程处理。

在一些实施方式中,并行化电路在从内部存储器供应在序列中的加载指令的结果时验证所供应的值确实匹配由加载指令从外部存储器取回的实际值。如果发现不匹配,则并行化电路可以刷新后续的指令和结果。任何合适的验证方案都可用于该目的。例如,如上面所解释的,并行化电路(例如重命名单元)可以添加执行验证的指令或微操作。实际的比较可以由alu或者可选地在lsu中执行。

如上面所解释的,并行化电路还可以例如基于指令的符号表达式的格式来验证没有介入事件导致在所供应的值与外部存储器中的实际值之间的不匹配。

在又一些其他实施方式中,并行化电路可以最初假定没有介入事件影响所讨论的存储器地址。如果在执行期间某个验证机制失败,则并行化电路可以推断出可能存在介入事件,并且避免从内部存储器供应结果。

在一些实施方式中,并行化单元可以禁止在外部存储器中执行加载指令。在实施方式中,不是禁止加载指令,并行化电路(例如重命名单元)将加载指令修改为执行上述验证的指令或微操作。

在一些实施方式中,并行化电路将来自内部存储器的加载指令的结果只供应给与一个或更多个特定流控制轨迹(例如,包含加载指令的轨迹)相关联的后续代码。在这个上下文中,并行化电路所考虑的轨迹可以是由代码遍历的实际轨迹,或者预期将被遍历的预测轨迹。在后一种情况下,如果预测失败,则后续代码可被刷新。在可选实施方式中,并行化电路将来自内部寄存器的加载指令的结果供应给与任何流控制轨迹关联的后续代码。

在一些实施方式中,从内部寄存器分配结果的决定和/或在用于添加或修改指令或微操作的代码中的位置的识别也可以考虑诸如在程序代码中的加载指令的程序计数器(pc)值、程序地址、指令索引和地址操作数的因素。

在一些实施方式中,ma寄存器可以驻留在具有与处理器的其他寄存器不同的特性和要求的寄存器文件中。例如,该寄存器文件可以具有来自lsu的专用写端口缓冲器,以及来自其他执行单元52仅读端口。

上面的示例指访问在代码区中的存储器地址的单个可预测模式的加载指令的单个序列。然而,通常并行化电路可以在相同代码区中识别并处理加载指令的两个或更多个不同序列,这些加载指令访问存储器地址的两个或更多个相应的模式。

如上面所解释的,并行化电路可以在与所讨论的代码区有关的记分板中存储关于加载指令序列的识别以及关于存储器地址的可预测模式的信息。

在上面的图2-6中给出的示例中,在存储器访问指令和因而产生的行动(例如,添加或修改指令或微操作)之间的关系在运行时间处被执行。然而,在可选实施方式中,这些功能中的至少一些可以由编译程序代码以用于处理器20执行的编译器来执行。因此,在一些实施方式中,处理器20部分地基于由编译器嵌入在程序代码中的提示或其他指示来识别在存储器访问指令之间的关系并对其起作用。

因此,将认识到的是,以上描述的实施方式是通过示例引用的,并且本发明并不限于上文已具体示出和描述的内容。相反,本发明的范围包括上文所描述的各种特征的组合及子组合以及本发明的变型和修改,所述变型和修改将在本领域的技术人员阅读上述描述之后想到且在现有技术中未被公开。通过引用并入本专利申请中的文件被视为本申请的组成部分,除了任何术语在这些并入的文件中在某种程度上以与本说明书中明确地或隐含地作出的定义冲突的方式被定义之外,应该仅考虑本说明书中的定义。

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