3、流水线读操作
  前面的例子说明了U流水线访问L2 Cache命中,处理器从L2 Cache读取数据进行Cache行填充,以及V流水线访问L2 Cache不命中,处理器从主存中读取数据进行Cache行填充的操作过程和时序。如果U、V流水线在访问L2 Cache时全命中,两者都要从L2 Cache中读取数据进行行替换,Cache控制器又是怎样操作呢?为此,Pentium定义了流水线操作方式,这种又称为背靠背的总线周期提供了最高的总线传送速率。
  以下例子假设流水线U和V执行的指令和前面相同,U和V都在L2 Cache中找到了目标双字的副本,L2 Cache便启动地址流水线功能。图5- 是一个U、V流水线进行流水线化猝发读的时序图。为了讨论方便,我们称U流水线的访问为周期A(Cycle A),V流水线的访问为周期B(Cycle B)。时序图(图5-18)中的时钟序列1~11分别称为t1、t2 … t11。
  首先开始为U流水线的L2 Cache访问。处理器在T1状态输出包含目标双字的那个四字的起始地址(00000050H)和总线周期定义,并将ADS#置1,指示当前总线上的地址和总线周期有效。通过设置CR0的CD位把PCD信号置为0。
  当L2 Cache收到流水线U的访问地址,就开始在目录中查找,发现Cache中有目标行的副本,于是在T2状态将KEN#信号置0、BDRY#置0,并把第一组"四字"放到数据总线上。同时,L2 Cache驱动NA#信号有效,向处理器申请开始下一个周期的访问;把WB/WT#信号置0,通知处理器按照S状态执行即时写回政策。
  处理器在第一个T2周期末了即第二个T2周期的开始对KEN#、WB/WT#、NA#和BRDY#的采样。采样到BRDY#信号有效,处理器锁存由L2 Cache送到数据总线上的第一个四字(50h到57h)。采样KEN#为0,处理器知道可以将传输内容放入内部Cache。采样WB/WT#为0,处理器将按照S状态存储数据。
  NA#为0,表示L2 Cache支持地址流水线操作,并请求处理器提前开始下一个总线周期。处理器采样到有效的NA#以后,结束周期A的地址和总线周期定义信号,准备开始周期B。
  处理器读取了第一个四字以后,在每个时钟周期的上升沿继续对BRDY#信号进行采样,在后续三个连续时钟周期(t5、t6、t7)采样到BRDY#信号为0,连续读取后面三个"四字",完成周期A的数据读取。并把它们存在内部Cache最近最久未被使用的行中,将该行的状态位设置为S(因为周期A的WB/WT#信号被采样为0)。
  在处理器采样到NA#信号有效的一个时钟周期之后(t5)启动周期B,为流水线V进行L2 Cache访问。处理器在T12状态输出包含流水线V要访问的目标双字的四字起始地址(0000008CH)和总线周期定义,并将ADS#置1。这一过程是和周期A的数据读并行执行的,此刻,周期A的猝发读正在进行当中。
  L2 Cache在目录中查找,确认V流水线L2 Cache命中。紧接着,又把NA#信号置1,开始请求处理器进行下一个周期(周期C)的传送。L2继续保持KEN#和WB/WT#信号为0(t6),表示B周期传送的数据可以放在Cache中,并仍旧执行即时写回政策。L2 Cache控制器在完成周期A的行填充以后,就开始周期B的Cache行填充,… 。
  地址流水线功能使得处理器可以将周期B的地址在周期A结束之前放入地址流水线,而不需要在流水线U和流水线V的行填充过程中插入空闲周期。L2 Cache可将周期B的第一个四字紧接着周期A的4个四字传输给处理器。后面的四字都可以在一拍中完成,直到行填充结束。
  仔细阅读时序图,可能会产生这样的疑问:T1为地址周期,处理器在T1发出地址信号,紧接着的T2是数据周期,L2 Cache根据地址查询目录命中以后,在T2将第一个四字的数据送上数据总线,与此同时,驱动NA#为有效状态,请求处理器提前开始下一个总线周期。处理器在第二个数据状态对NA#信号采样,并在紧接着的(新)地址(老)数据周期T12开始启动下一个总线周期,将新的地址送到地址总线上。处理器从第一总线周期的地址状态到第二总线周期地址状态经过了3个时钟周期,而每个总线周期却要使用4个时钟周期传送4组数据。流水线发送地址的时间间隔短于数据传送周期将会导致流水线负载不均衡。为此,Pentium存储管理部件规定,处理器如果已经发出了两个访问周期的地址,但是还没完成读操作时是不会启动下第三个总线周期的。在这个例子中,周期A在t6的末尾结束,这时只有周期B还没有完成,所以周期C可以在t8开始。周期B在t10的末尾结束,只有周期C正仍在进行,周期D在t12开始。