MIPS R10000超标量微处理器

来源:互联网 发布:我的世界端口号 编辑:程序博客网 时间:2024/04/28 15:58

MIPS R10000超标量微处理器

MIPS R10000 采用64位第四代MIPS指令集体系结构的动态超标量微处理器。它在每个时钟周期内能够获取解码4条指令,并能够动态地将它们发送到五级完全流水、低时延的执行单元中。在分支之前能够推测获取指令并执行。指令按顺序逐步完成。尽管有时执行指令会发生故障,但是处理器仍然提供连续的内存的一致性和精确异常处理。

 

 

R10000 是为了高性能,缺少存储空间的大型应用而设计的。通过推测执行,它能够尽早地计算内存地址并初始化高速缓存。它的分层、无锁存存储系统能够通过两级组联写回式高速缓存隐藏存储时延。图表1显示了R10000系统配置,并列出了它的特点。

图1 系统配置。簇总线直接连接4个芯片
无序超标量处理器十分复杂。为了应付这种复杂性,R10000采用模块化设计方法,拥有许多规则结构的控制逻辑,如活动列表、寄存器映射表和指令序列等。

设计原理

 
存储带宽和时延限制了许多程序的性能。因为封装和系统开销限制了这些资源,处理器必须有效使用它们。

 

R10000 实现了寄存机映射和通过高速缓存相互重叠来操作的无锁高速缓存。因此,如果一个指令没用命中高速缓存,该指令就必须等待高速缓存填充操作,但其他指令就会继续乱序执行。这会使内存使用增加且有效减少时延,因为当处理器执行其他指令时,高速缓存填充操作就是早开始进行并且可以高达四个填充操作并行。这种高速缓存设计方式成为无锁式高速缓存,因为高速缓存的太冲并不会阻塞后续的高速缓存行的存取操作。

处理器依赖编译器支持的I/O优化的指令序列。这种技术尤其对于数据数组有效,如那些使用浮点的应用。对于这些队列,一个复杂的编译器能够优化特定的高速缓存组织。然而,编译器优化效果对于使用整形的标量应用不太有效,因为编译器难以预测哪些指令会使高速缓存未命中。

R10000设计包括基于操作可用性的动态序列指令执行等复杂硬件。这种硬件能够立即适应高速缓存未命中而造成的指令延迟。这种处理器前瞻执行高达32个可能并行的指令。指令窗足够大能够无视将二级高速缓存填充操作时延。但只有指令窗很大能够无视部分主存时延。

它是一个相对容易的非阻塞高速缓存加入到乱序处理器,因为它已经包含了指令间协作依赖包含机制。

实现

我们利用0.35微米CMOS技术在一块16.64×17.934毫米的芯片实现了最初的R10000处理器。这个298平方毫米的芯片包括了680万个晶体管,其中它的主缓存阵列适用了440万个晶体管。我们采用完全定制设计实现数据通路和时间要求严格的控制逻辑,广泛采用动态锁存型逻辑。我们使用静态寄存器为基础的逻辑合成了非关键线路。

 

系统的灵活性

备用配置使R10000作为单处理器或者中多处理器集群广泛应用在系统中。该系统采用的snoopy协议或者基于目录的高速缓存已执行协议。R10000处理器的二级缓存范围是512字节到16384字节。
 

操作概述

图2显示了一个框图和一个R10000的流水时序图。其中有六条独立流水线。


 图2 R10000框图(a)和流水线时序图(b)。框图显示了流水线从左到右的相对应的流水线时序

取值在流水线的1-3阶段。在阶段1中,R10000获取并排列后四条指令;阶段2,R10000进行解码、重命名这些指令,同时为跳转和分支指令计算目标地址;阶段3中,R10000将重命名的指令写入序列,并读取位状态表来决定是否操作数是否已经完成。指令将会在序列中等待直到所有操作数准备完成。

当序列在阶段3中执行,五条执行流水线开始执行。在第3阶段后半处理器开始从寄存器文件中读取操作数,并在第四阶段开始执行。整数型流水占据一个阶段,装载流水线占据两个,而浮点型流水占据3个。处理器在下一阶段前半部分向寄存器文件写入结果。

整型和浮点型部分有单独的指令序列、寄存器文件和数据通路。这种分离能够最大限度减少导线长度,并允许完全并行操作。总之,两个寄存器文件相对于整合单元更需要自由的寄存器,但他们体积小,因为每个寄存器很少读写端口。

 

取指令

对于良好的性能来说,处理器在更高带宽下取指解码比执行指令更为重要。保证指令充满序列非常重要,这样就能够乱序执行指令。最终,处理器取到比它能够执行指令数还多的指令,因为它摒弃预测分支发生错误的指令。

如图3所示处理器在阶段1中取指令。指令缓存包含了地址标志和数据部分。实现两路组相连,每一个部分都要有并行序列。处理器比较两个变量地址转换到物理地址来从正确的地址选择数据。8项指令转移查找缓存包括了主TLB的一个子集。




图3  获取指令——流水线第一阶段

该处理器在16字指令高速缓存行中并行获取四条指令。如图4所示,我们通过对高速缓存的读出放大器进行小的修改来实现。每一个读出放大器的存储阵列4位宽,还有4对1多路开关来选择一列(其代表了一个指令)来获取指令。R10000通过对每个独立的指令进行单独选择信号来获取。如果可能的话,指令可以轮换来保证它们能够按顺序解码。这种顺序能够减少大量的依赖逻辑。



图4 从指令缓存中非对齐获取指令

通常,处理器在下一个周期中解码所有四条指令,除非该队列或活动列表已满。为了简化顺序读取的时序,未及时解码的指令仍要留在8位指令缓存中。

分支单元

分支指令经常发生,并且需要快速执行。然而,处理器通常直到解码后的多个周期内也不能决定分支方向。因此,处理器预测了一个条件分支的方向,那么将会沿着预测的路径进行取指令。预测一个基于512项分支历史表的2位算法。这个表有位11:3的分支指令的地址进行索引。仿真结果显示,Spec92整型程序预测成功率为87%。

在MIPS体系结构中,处理器在目的地址执行指令之前通常会跳转或分支执行下面的指令。在一个流水线标量处理器中,目标指令从高速缓存中读取目标指令时,这种延迟槽指令能够无损耗的执行。这种技术在早起的RISC微处理器能够有效提高分支。然而,对于一个超标量设计,它并没有性能上的优势,但我们仍然保留了R10000的兼容性。

当程序执行需要跳转或分支时,该处理器抛弃所有已经超出延迟槽的获取的指令。它加载跳转目标地址进入程序计数器并在一个周期延迟之后从高速缓存中获取新的多个指令。这里介绍的“泡沫分支”周期中,R10000没有解码任何指令。

分支堆栈。当处理器解码一个分支的时候,处理器将通过一个四目分支栈来保存它的状态。它包含了备用分支地址、整型和浮点映射表的完整备份和杂项控制位。尽管堆栈作为一个单一逻辑实体,它在物理上分布更接近它的信息副本。

当分支堆栈已经满了,处理器将会继续解码直到它遇到下一个分支指令。一直解码,直到未决定的分支问题得到解决。

分支确认。即使有些分支即将要执行,处理器也会验证每一个分支预测的确定条件。如果预测不正确,处理器会立即终止所有沿着错误预测路径获取的指令,并恢复其分支栈内的状态位。

沿着错误预测路线获取指令可能不需要高速缓存读写来启动。在这种情况下,指令集高速缓存是无锁的,而指令集高速缓存在处理器获取正确预测路径时需要填充完整。这样进行填充高速缓存十分容易,因为程序执行需要快速获取其他分支方向,比如说一个循环的结束。

一个四位的分支标记——对应着分支堆栈的条目——会伴随队列中和执行流水线的每一条指令。这个标记表明待处理分支与指令之间的依赖关系。如果这些分支预测失败了,当分支决策改变,处理器会立即中止这些指令。每当R10000改变分支的时候,它都会在流水线中重置相应的屏蔽位。

解码逻辑

R10000处理器能够在阶段2中同时解码映射4条指令,同时在阶段3开始的时候将它们适当地写入指令队列。

当活动列表或者队列满了的时候停止解码操作,但很少有取决于解码指令类型的解码限制。主要例外情况包括了整数除法和除法指令。它们的结果将会进入两个特殊的寄存器——HI 和 LO。没有其他指令有多个结果寄存器。我们不需要为这些不常使用的指令设置太多了的逻辑,相反,它们在活动列表内占据了两个槽。当寄存器解码这些指令的时候,它不会在同一周期内解码其他后续指令。(此外,处理器也不能够在一个周期内将一个整数乘法或除法指令当成第四个指令进行解码。)

指令的读取和修改操作确实控制着寄存器的连续执行。处理器仅仅能够运行这些少数在流水线为空时在内和操作系统模式的指令。这些限制对于处理器的整体性能并没有任何影响。

寄存器映射

图5显示了R10000的寄存器映射硬件。为了打乱原有程序指令的执行顺序,处理器必须记录寄存器操作数、内存地址和条件位的依赖关系。(条件位是指为浮点比较指令设计的静态寄存器的8位。)为了确定寄存器的依赖关系,R10000适用了寄存器重命名。它决定了内存地址依赖于地址队列。它设定了在其值确定解码时每一个条件位操作。如果不是确定的值,它将通过浮点比较指令的标志来重命名该位,并确定其值。


图5,寄存器重命名,流水线第二阶段。R10000在预解码指令阶段进行重新排列,并在填充阶段将指令写入缓存中。高速缓存中的指令格式包含一个额外的4字段单元

从一个程序员的角度来看,指令应该在程序内顺序执行。当一个指令装入一个新值并传入它的目的寄存器,新值就能够立即被随后的指令使用。然而,一个超标量处理器能够同时执行多条指令,指令的值也不能够立即传给后续指令。通常,下一个指令必须等待它的操作数有效,但可能后续指令的操作数都能使用了。

R10000通过乱序指令后续指令获得更高的性能,但程序员是看不到这些指令的重新排序。任何乱序产生的结果在先前指令完成时都是暂时的。这些指令执行,其结果也会作为处理器的状态。到指令完成之前,如果预测错误或分支异常都可以终止进行。它的逻辑目标寄存器的内容都可以通过恢复以前的映射来恢复原来的数据。

对于多数处理器来说,对硬件寄存器文件中的引用指令区和物理寄存器的逻辑寄存器数据并没有区分。每一个指令区直接对应相应的寄存器。然而,我们的重命名策略动态映射逻辑寄存器数据到物理寄存器的数据。处理器会将每一个新的结果写入一个新的物理寄存器。映射后,处理器仅通过比较物理寄存器数据获取依赖关系,同时也不再需要考虑指令顺序。同时,这些物理寄存器和逻辑寄存器与物理寄存器的映射关系对于程序员也会是不可见的。

R10000执行在解决先前指令所有的依赖关系之后才会动态执行指令。也就是说每一条指令必须等待所有的操作数计算出来才能够执行。无论最初的指令序列如何,R10000都能够执行该序列。为了正确执行指令,处理器必须判断每一个操作寄存器是否已经准备好了。因为逻辑寄存器的数据可能是模棱两可的操作值,所以这是十分复杂的。礼服,如果多个指令同时在一条流水线中执行相同的逻辑寄存器,这个寄存器很可嗯呢该同时多次加载不同的值。

每一个物理寄存器都会在空闲列表的每一个任务后写一次。物理寄存器写入的时候一直是忙碌状态。如果后续指令需要它的值,这条指令会等到物理寄存器写入。当寄存器写入之后,指令还在准备且它的值也不会改变。当一个后续指令改变了与它一致的逻辑寄存器时,程序不会在需要旧值,就饿物理寄存器也会重新使用。因此,物理寄存器经常是不确定的值。

处理器中一个有33个逻辑整型寄存器(1至31号、Hi和Lo)和64个物理整型寄存器。(没有整形寄存器0,零操作字段表示零,一个零目的域表示未存储的结果。)同时,处理器有32个逻辑浮点寄存器(0至31号寄存器)和64个物理浮点寄存器。

寄存器映射表。单独的寄存器文件存储处理器独立重命名的整形和浮点型寄存器。整型和浮点型映射表包含了当前逻辑寄存器映射到物理寄存器的信息。处理器使用5位的指令域选择逻辑寄存器。在相应寄存器文件中通过六比特位地址来识别物理寄存器。

浮点表通过一个32×6位的多路RAM中寄存器f0至f31映射。整形表通过一个33×6位的多路RAM中的寄存器r1至r31、Hi和Lo来映射。(对于整型乘法和除法指令的隐藏目的寄存器Hi和Lo有特殊的访问逻辑。)

这些映射表有16个可读端口和4个写端口同时映射4条指令。每一个指令读取单个操作数和一个目的寄存器的映射。处理器在指令队列中写入当前操作数映射和新目的映射,同时活动列表保存了此前目的映射。

空闲列表。整形和浮点型空闲列表包含了当前未分配的物理寄存器列表。应为处理器同时解码执行4条指令,其中列表包括了4个并行8位长的循环FIFO列表。

活动列表。活动列表记录了处理器正在执行的所有指令,并附加每个处理器解码的指令。当指令之行结束之后或者错误的分支预测和异常导致指令中止,活动列表会移除这些指令。活动列表也包含4个并行8位长度循环FIFO列表能够执行高达32个指令。

每个指令都通过5位标志同活动列表的地址比较来确认。当一个执行单元完成一条指令时,指令会将它的标志送入活动列表,并标记它的完成位。

活动列表包含了逻辑目的寄存器号和没一条指令的旧物理寄存器号。一条指令的完成会生成新的映射,所以旧的物理寄存器需要返回空闲列表来重新被使用。

然而, 当异常发生时,随后的指令并不会完成。相反,处理器会将旧的映射关系从活动列表中保存起来。R10000不会用相反的顺序来每个周期映射4条指令,以防止两次重命名为相同的逻辑寄存器。尽管这样比储存分支慢,但这种意外比分支预测还要罕见。处理器通过重新读取指针返回新的物理寄存器到空闲列表。

忙位表。对于每一个物理寄存去,整型和浮点型忙位表都包含一位来显示是否寄存器当前含有有效值。每个表都采用一个64×1的多端口RAM。当空闲列表内移除相应寄存器号时,忙位表会设置改位为忙。当执行单元将值写入到寄存器中,忙位表会重置该位。十二个读写端口确定每四个新解码指令的三个操作数状态。序列采用其他三个端口来记录特殊的指令,例如整型浮点型寄存器文件的移动。

指令序列

R10000会依据类型将每条解码指令除了跳转和无操作数指令放入三个指令队列中的一个。只要有空间,序列就能够接受新指令的任意组合。

该芯片的周期时间束缚着我们对序列的设计。例如,我们想要通过两个寄存器文件读取端口获取每一个发出的指令来避免延迟仲裁和复用操作数总线。

整型队列。整形队列包含了不定序的16个条目,当指令解码时会分配一目到每一个整形指令中。只要指令发送到ALU中,序列就会释放对应的条目目。

对于一个指令,只有一个ALU能够获取执行优先权。因此,分支和移位指令会优先使用ALU1,整型乘法和除法指令优先使用ALU2。为了更简单点,队列中的位置比指令实现对于指令发送更有优先权。然而,轮询请求电路会提升旧指令请求ALU2的优先权。

图6显示整型队列条目的内容。对于一个指令,只有一个ALU能够获取执行优先权。因此,分支和移位指令会优先使用ALU1,整型乘法和除法指令优先使用ALU2。为了更简单点,队列中的位置比指令实现对于指令发送更有优先权。然而,轮询请求电路会提升旧指令请求ALU2的优先权。

图6整型指令队列,仅有一个发送端口。队列能够同时发出两条指令。

操作数C含有状态位的值或通过浮点比较指令来设置其值的标志。总体而言,16目中的每一个都包含了6位比较码。

队列中将功能码和立即值发给执行单元。如果一个指令因为错误的分支预测而中止,分支会标记其目的地。在处理器在该阶段完成指令的时,标志会在活动列表中设定完成位。

整型的单周期延迟说明发杂的整型序列时序和逻辑。在一个周期内,序列必须发出两条指令,检测哪些操作数就绪并请求相关指令。图7a显示了这个过程。

为了实现两个周期的负载延迟,假设负载竟会成功完成,依赖于一个整型负载的结果必须暂停发出。当负载录取数据缓存时,相关指令必须在执行的前一周期发出。如果由于缓存未命中或依赖问题造成装载失败,相关依赖指令的发送必须被中止。图7b显示了这一过程。

图7 释放寄存器依赖整型队列(a)和指令的试探性发送依赖于早期装载的指令

地址队列。地址队列含有16条目。不同于其他两个队列,地址队列是可以保留期指令的原始顺序的循环FIFO队列。当处理器解码每一条装载存储指令时,队列会分配一个条目,当处理器完成该指令时,队列会移除该条目。队列使用指令顺序来决定内存依赖,最早的指令获取优先权。

当处理器还原一个错误的分支预测时,地址队列会移除所有通过恢复写指针来恢复的分支解码指令。队列使用类似在整型队列逻辑将指令发送到地址计算单元,所不同的是这两个逻辑只包含了两个寄存器操作数。

地址队列比其他的队列都复杂。如果装载存储指令具有内存地址依赖或数据缓存中缺失,地址队列需要重试操作。

两个16位×16位的矩阵追踪内存访问的相关性。每一行每一列对应着队列的条目。第一个矩阵通过追踪相同的缓存集避免了不必要的缓存颠簸(虚拟地址135)。无论哪一种方式,都可以用于乱序执行指令。但是存在对于相同缓存集的不同线路两个或两个以上队列条目,另一个方式是保存访问缓存集的最旧的条目。第二矩阵追踪装载了作为挂起存储指令相同字节的指令。它通过比较双字地址和8比特位字节标记匹配。

每当外部接口访问数据高速缓存时,处理器都会比较索引和队列中所有挂起条目。如果一个装载条目和填充地址匹配,它就会直接将填充数据放入它的目的寄存器中。如果一个条目匹配了无效指令,那么该条目状态会被清除。

虽然地址队列乱序执行装载存储指令,但他还是保持着连续存储器的一致性。然而,外部接口能够通过在指令装载到寄存器后装载指令完成之前使缓存行无效来违反存储器一致性。在这种情况下,队列创建一个加载指令的软异常。这种异常会清空流水线,中止装载和其他后续指令,因此处理器不适用旧数据了。之后,处理器会中止异常,从中止加载指令开始正常运行。(这种策略保证了前行进程,因为旧指令会在其他指令完成后立即完成。)

存储质量要求地址队列和活动列表之间的具体协调。当存储指令完成后,队列必须精确地写入缓冲。

MIPS架构通过加载链接(LL)和条件存储(SC)指令来模拟内存原子操作。因为不需要锁定内存,所以这些指令不需要复杂的系统设计。在典型的序列中,处理器通过LL指令加载一个值,测试并修改它,之后再通过SC指令有条件的存储。只要在缓存中的值和链接词没有冲突,SC指令就能够写入内存。处理器使用1或0加载其结果寄存器显示内存是否写入。

浮点队列。浮点队列包含16目。同整型队列相似,但浮点队列不包含立即值。由于额外的布线延迟,浮点负载有三个周期的延迟。

寄存器文件

整数和浮点寄存器文件都包含64个物理寄存器。执行单元直接从寄存器文件读取写回操作数。结果可能绕过寄存器文件进入操作数寄存器中,但没有独立结构,如保留站或宽数据路中的重排序缓冲器。

整型寄存器文件有7个读端口和3个写端口,包括了2个专用的读端口、每个ALU的一个专用写端口和2个专用于地址单元的的读端口。整型寄存器第七个读端口处理存储、跳转寄存器和转向浮点指令。第三个写端口用于处理装载、分支链接和转回浮点指令。

一个段的64字×1条件文件显示是否对应的物理寄存器的值是非零的。它的三个写端口能够同时操作三个整型寄存器文件。它的两个读端口允许整型浮点型条件移动指令来测试单个状态为非整个寄存器。在寄存器文件中,该文件使用的面积比两个额外的读端口还少。

浮点寄存器文件含有五个读端口和三个写端口。加法器和乘法器都各含有两个专用读端口和一个单独的写端口。第五个读端口处理存储和移动指令。第三个写端口处理加载和移动指令。

整型执行单元

每个周期中,整型队列能够发送出两条指令到整型执行单元中。

整型ALU。两个ALU各包含一个64位加法器和逻辑单元。此外,ALU1包含了一个刘思伟转换器和分支条件逻辑,ALU2包含了一个部分整型乘法阵列和整型除法逻辑。图8显示了ALU1框图。每一个ALU都有两个能够从寄存器文件装载操作数的64位操作数寄存器。为了达到一周期的延迟,寄存器文件的三个写端口会通过旁路进入操作数寄存器。



图8 ALU1框图

整型队列控制所有的ALU。它提供了功能代码、立即值和旁路控制等。

整型乘法和除法。ALU2迭代计算整型乘法和除法。如上文提到 的,这些指令包含了两个目的寄存器——Hi和Lo。对于乘法指令,Hi和Lo包含了双精度的高低两部分。对于除法,它们包含了余数和商。

ALU2 使用Booth算法计算整型乘法——即通过乘法器的每两位产生部分结果。这种算法每个周期产生并累计四个部分积。ALU2在指令发出的第一个周期和最后存储结果的两个周期工作。

为了计算整型除法,ALU2使用一种不需要存储的算法每周期计算一位。ALU2在整个操作都是工作的。表格1列出了普通整形指令的等待时间和重复率。


 


浮点执行单元

图9显示了浮点执行单元的尾数数据路径(指数逻辑没有画出)。加法器和乘法器有三级流水线。两个单元都是具有单周期重复率完全流水线。结果能够绕过两个或三个周期的延迟。所有的浮点操作数将从浮点队列中发出。

图9 浮点执行单元框图

在浮点寄存器文件中采用IEEE标准574的单精度或双精度格式封装浮点值。执行单元和所有内部旁路使用明确存储隐藏位和分离出11位指数和53位尾数的非压缩格式。读取时操作数解压缩,结果在写回之前压缩。压缩与解压缩依据单精度和双精度的选择,并通过双输入多路复用器来实现。这种逻辑是在执行单元和寄存器文件之间的。

浮点加法器。加法器做浮点加法、减法、比较和转换操作。第一阶段内减去操作数的指数,选择较大的操作数,然后在55位右移对齐较小的尾数。第二阶段是根据操作盒操作数的迹象,增加01减去尾数。

数量级大的加法会产生进位,正常传值的情况下需要右移一位。通常,处理器需要对结果进行四舍五入。为了避免额外的延迟,一个双进位链加法器能够同时产生+1和+2的两种和。如果操作数需要右移后正常化,处理器会选择+2链。

另一方面,一个大数量级的减法可能引起大量的消除,产生高阶零的结果。前导零预测能够决定电路中有多少由减法产生的高阶零。它的输出控制着一个55位左移正常化结果。

浮点乘法器。乘法器在完全双精度序列中完成浮点乘法。因为乘法器没有加法器忙碌,所以乘法器包括执行移动和条件移动操作的多路转换器。

在第一个周期中,单元会使用布斯算法改写53位乘法器的尾数、选择27位部分结果(通过布斯算法的加密,仅有一部分结果需要乘法器的两位操作)。压缩树使用(4,2)阵列来进位保存加法器,加法器计算四位得出两个和与进位输出。在第二周期期间,使用一个106位的进位传播加法器来获得106位的和与进位值。

浮点除法和平方根。两个独立的迭代单元计算浮点除法和平方根操作。每一个单元都使用SRT算法在每个迭代周期生成两位。除法单元通过每个周期生成四位来级联每一周期的两个阶段。

这些单元与乘法器共享寄存器文件端口。每个操作数先占据两个周期。第一个周期会先发出指令,并从寄存器文件中读取操作数。操作结束后,单元会利用第二个周期将结果写入寄存器文件。

表格2列出了常用浮点指令的延迟和重复率。

存储器层次结构

内存延迟对于处理器性能影响极大。为了高效运行大型项目,R10000利用两级组相联高速缓存实现了一个无锁的内存层次结构。芯片上的主要指令和数据高速缓存能够在低延迟高带宽下同时工作。芯片同时也控制着一个大型的外部二级高速缓存。所有的高速缓存使用LRU替换算法。

同时所有的主缓存都是用虚拟索引地址和一个物理地址的标志。为了最大化降低延迟,处理器能够同时利用TLB进行地址转换和连入主缓存。因为每个缓存通路都有16Kb大小(最小虚拟页的4倍大),两个虚拟索引位和物理地址标志位大小不同。这种技术是为了简化高速缓存的设计。使用该设计的缓存性能好,同时在程序利用并立的虚拟索引指向同一个页时也表现良好。处理器存储这两个虚拟地址位作为二级缓存标志位的一部分进行保存。二级缓存控制器能够检测到任何的错误,并确认主缓存只保留了每一个缓存列唯一副本。

加载、存取单元。 图10所示加载、读取单元和数据缓存的框图。地址队列加载、读取指令到地址计算单元和数据缓存中。当该缓存不忙,装载指令能够同时进入TLB、缓存标志数组和缓存数据数组中。这种分布接入的结果造成了双循环加载延迟。



图10 地址计算单元和数据缓存框图

地址计算。R10000使用两个64位寄存器或者一个寄存器和16位即时空间来计算虚拟内存地址。这导致了ALU或数据缓存器绕过了寄存器文件到操作数寄存器中。此时TLB会将这些虚拟地址转换成为物理地址。

内存地址转换(TLB)。MIPS4代体系结构定义了64位寻址。实际实现中采用最大寻址宽度来降低TLB和缓存标志队列的开销。R10000全相连转换旁氏缓冲器将44位虚拟地址转换成40位物理地址。这种TLB设计与R4000设计相同,但我们将R10000提升到64个条目。每一个条目映射一组虚拟页,并独立选择在4Kb到16Mb之间的4个随意大小的页面。TLB包括了能够比较虚拟地址的内容可寻址处理器(CAM部分)和一个包含相应物理地址的RAM部分。

主指令缓存。一个32K的指令缓存包含了8192个指令字,每一个都预先解码成一个36位的格式。处理器在解码扩展格式上比原来的指令格式更加快速。特别是,额外四位即功能单元能够执行指令。这种预先解码也能够重新排列操作数(和目的地),为每一个指令选择字段放在相同的位置上。最后,处理器修改一些OpCode来简化整型解码和浮点目的寄存器。

并行处理器同时从缓存行里获取四个指令,同时缓存命中逻辑所要选择的指令。这些指令不需要一致的四字地址,但他们不能够交叉在16字缓存行里。(参见图3)

主数据缓存。数据缓存为了增加带宽插入了两个16Kb大小的槽。处理器依靠以下四个需求通道处理每个槽的标志和数据数组:

外部接口(填充数据,插入等),

为新的计算地址进行标志检查,

 重新加载指令,和

获取存取指令。

为了简化接口和减少所需要的缓冲,外部接口设置了队列的优先级。它的请求法正在高速缓存读写的两个周期之前,所以处理器能够依靠管道分配剩余资源。

数组缓存有8个字行大小,这是一个为了方便的妥协。更大的字长会减少标签RAM队列面积和适度降低未命中率,但在填充高速缓存时会消耗更多的带宽。设置成一个8个字大小,二级缓存的带宽就能够支持三到四个重叠填充。

每一个数据缓存的两个槽包括了两个逻辑队列来支持双向组关联。然而不同于平时的设置,缓存通路在这些有效支持不同带宽通路的队列中轮换,如图11所示。

 

图11 数据缓存内的通路设置

处理器同时从两个高速缓存通路读取相同的双字,因为它能够并行检测缓存标志,并能够从正确的缓存通路里读取数据。处理器将正确的通路上的双字丢弃。外部接口通过两个双字并行填充或写入四字。因为处理器事先知道了正确的缓存,所以能够实现。

这种安排有效地使用了缓存读出放大器。每一个放大器包括一个4-1多路复用装置,因为每个放大器都有4列存储单元。我们通过改变逻辑选择实现了这个特性。

二级缓存。我们使用外部同步静态RAM芯片来实现512Kb到16Mb、双路组相连的二级缓存。根据系统需求,用户能够配置二级缓存通路是16字或者32字。

 组相连设置能够减少冲突失误、增加可预测性。然而对一个外部缓存来说通常需要特别的RAMS或者许多接口引脚来解决组相连。相反,R10000仅用标准同步SRAM和一个额外的地址引脚实现了双向虚拟组相连二级缓存。

图12显示了高速缓存如何利用管道填充。一组RAM包括了两条高速缓存通路。一个片载位队列能够追踪每个缓存组的最近使用。在主高速缓存未命中之后,将会通过这条路在二级缓存中读取两个四字大小的数据。读取其中一个四字时会一起读取标志位。通过额外的地址引脚绑定的方式,另一个替换路的标签会随着第二个四字一起读取。



 图12 从组相连的二级缓存中填充数据。在这个例子中,二级缓存的时钟同处理器内部时钟一致。实际中,二级缓存时钟慢一些。

三个例子会发生:如果第一路命中,数据会被立即数用,如果是替换路命中,处理器会再次读取二级缓存。如果都没有命中,处理器会在内存中查找数据填充二级缓存。

大型外部缓存需要用纠错码来保证数据完整性。R10000保存了一个9位的ECC码和每四字大小的奇偶校验位。额外的校验位能够减小延迟,因为他们能够快速检测并阻止无效数据的使用。如果处理器检测到一个矫正错误,它会试着重新通过双周期校正通路读取数据。

我们能够配置接口来为读取修改通路。尽管这样会使延迟增大,但它允许冗余锁步处理器在校验误差存在的情况下保持同步。

系统接口

R10000通过64位分离事务系统总线与数据地址多路复用来和外界通信。这种总线能够连接高达8个读请求的四个R10000芯片。

系统接口良好的支持了并发请求和乱序操作。高速缓存填充在高达四个来自二级缓存或主存的未付读请求下也是无锁的。这些都是有未命中处理表来控制的。

缓存缓冲区包含了四个未付读请求地址。从这些请求中返回的存储数据都被存在四目传入缓冲区内一片与他们能够在某一命令下能够被读取。传出缓冲区有高达五个Victim块写回内存。当总线连接的二级缓存无效时,缓存需要写入第五条目中。

一个8目集群缓冲在系统钟先生追踪所有未完成的操作。如果必要的话,它要通过查询或令缓存行无效来确保缓存一致性。

当无缓存的装载、储存指令成为指令通道中第一个时,为缓存的装载、存储保指令都会执行。出其里通常为图形或其他设备写入使用无缓存保存。这样的序列通常含有大量的顺序同一地址访问。这种无缓存的缓冲会自动收集他们进入32字大小的块内来保护总线带宽。

时钟。一个芯片上的锁相环生成所有的时间与外部接口时钟同步。为了系统设计和灵活升级,独立时钟分频器能够给用户五个二级缓存和七个系统接口时钟频率的选择。为了提供更多的选择,我们的时钟基于管道时钟两倍的振动的锁相环。当管道运转在200MHz时,锁相环运转在400MHz。同时,用户可以配置系统接口以200、133、100、80、66.7、57或50MHz下运转。此外,用户可以单独配置二级缓存的频率为200MHz或66.7MHz。

输出驱动。数组缓冲驱动芯片输出针脚。用户可以单独配置每一组低压CMOS或HSTL标准。每一组缓冲设计都有独特之处。

图13表明了这些缓冲是如何连接的。系统接口缓存包含了额外的开放通道下拉晶体管,还需要提供驱动HSTL2类多路总线的额外电路。


图13 时钟和输出驱动

我们设计二级缓存数据缓冲来减少切换时的重叠电流峰值,为了近200个信号能够同时切换。

缓存地址缓冲使用快速标志极电晶体来快速驱动多个分布式负载。缓存时钟缓冲以最小的输出延迟来驱动低阻抗微分信号。低抖动延迟单元精准地对齐所有的时钟。这种延迟是静态配置的以校正印刷在电路板上的时钟网的传播延迟,所以这些在高速缓存中的时钟与处理器内部时钟同时到达上升沿。

测试性能。为了经济生产,一个微处理器芯片必须能够容易在高错误覆盖率下进行测试。R10000通过10个128位线性反馈移位寄存器来观察内部信号。这些内部测试点将芯片分为三个完全观察部分。

寄存器是独立结构才能够对处理器逻辑或对添加一个明显负载观察信号无影响。寄存器使用处理器时钟来保证同步行为并避免任何特别始终请求。寄存器对于调试和生产设施用处极大。

性能

我们现在在SGI挑战服务器上装载200MHz的R10000微处理器,而其他几个供应商也会因为R10000的特别设计开始在系统中使用R10000处理器。我们规划了如下的一个系统——200MHz R10000微处理器,4Mb的二级缓存(200MHz),100MHz 的系统接口总线和180ns的内存延迟。该系统性能表现如下:

    ·SPEC95 整型(最高值) 9

    ·SPEC95 浮点型(最高值) 19

这些数据是我们在R10000运行在上文中提到的设计系统中所表现的性能指标。我们按照MIPS Mongoose编译器早期版本编制的这些基准。

一个高效的超标量微处理器R10000具有快速时钟和无锁组相连内存子系统的特点。它的设计强调了并发性和隐藏延迟技术在大型真实程序中的高效运用。

 

 

0 0
原创粉丝点击