缓存系统
![]() |
| 图7:缓存子系统对比 |
Core微架构沿袭了Yonah的结构,借鉴了Netburst的位宽,综合了两者的优点。Core和Yonah均有专门的存储地址单元,而Netburst使用了快速ALU来计算存储地址,因此它并不需要这样的一个功能单元。Yonah L1数据缓存到核心的通道带宽为64bit,之前的Netburst的L1数据缓存到核心的通道带宽为128bit,新的Core微架构的L1数据缓存到核心的通道带宽为128bit。而二级缓存到L1数据缓存之间的通道位宽则均为256bit,因此只有Yonah的缓存内部总线带宽是比较特别的,从L1数据缓存到核心的带宽只有从L2缓存到L1缓存的一半。
Netburst微架构配置了16KB 双端口数据缓存,8-way,64个DTLB入口;Yonah和Core均配置了32KB 双端口数据缓存,8-way,前者128个DTLB入口,后者为256个DTLB入口。基于Netburst微架构设计的双核处理器,包括Pentium D、Paxville DP等等其L2缓存均为独享式。Yonah核心则采用了共享式L2缓存缓存设计,Core微架构则进一步将共享L2缓存的容量提升到4MB。
在乱序CPU中,通常会有多个Load操作和Store操作处于“in-flight”,对于部分有依赖关系的指令,处理器不能随意的进行排序。Core微架构缓存系统中的内存重排序缓冲(Memory Reorder Buffer,MOB)功能单元为了能更好的处理这些问题也做了一系列改进。
![]() |
| 图8:存储器别名示意图 |
如上图所示,第一条ALU指令的运算结果要Store在地址Y(第二条指令),而第九条指令是从地址Y Load数据,显然在第二条指令执行完毕之前,无法移动第九条指令,否则将会产生错误的结果。同样,如果CPU也不知道第五条指令会使用什么地址,所以它也无法确定是否可以把第九条指令移动到第五条指令附近。
内存数据相依性预测功能(Memory Disambiguation)可以提前预测哪些指令是具有依赖性的或者使用相同的地址的(地址混淆,alias),从而决定哪些指令是可以移动的,哪些指令是不可移动的。不过为了要判断一个Load指令所操作的地址没有问题,缓存系统需要查验所有的处于in-flight状态的store操作,这是一个颇耗费资源的过程。在Netburst微架构中,通过把一条store指令分解为两个uops——一个用于计算地址、一个用于真正的存储数据,这种方式可以提前预知store指令所操作的地址,初步的解决了数据相依性问题。在Netburst微架构中,内存重排序缓冲(MOB)的算法遵循以下几条原则:
- 如果一个对于未知地址进行操作的store指令处于in-flight状态,那么所有的load指令都要被延迟
- 在操作相同地址的store指令之前Load指令不能继续执行
- 一个Store指令不能移动到另外一个store指令之前
这种原则的问题也很明显,比如第一条原则会在一条处于in-flight状态的store指令所操作的地址未确定之前,就延迟所有的load操作,显然有些太保守了。根据某些机构的研究,在类EV6处理器中最多可以允许512条指令处于in-flight状态,但是其中的97%以上的load和store指令都不会存在地址混淆的问题。按照这个概率来看,假设所有的Load/Store指令不存在地址混淆现象是更合理的。
基于这种理念,Core微架构采用了截然相反的做法,该微架构中load指令可以基于一定的预测机制预先移动到具有未知操作地址的存储指令的附近。不过,当这种“冒险”失败之后,将会使得一条管线停滞(pipeline stall)。为了解决这个问题,Intel采用了一个动态别名预测器(dynamic alias predictor)来预测什么时候load指令不能被移动到store指令附近。这个预测是根据历史行为来进行的,据说准确率超过90%。
![]() |
| 图9:数据相依性预测机制的优势 |
如上图所示,我们需要载入地址X的数据,加1之后保存结果;载入地址Y的数据,加1之后保存结果;载入地址Z的数据,加1之后保存结果。如果根据Netburst的基本准则,在第三条指令未决定要存储在什么地址之前,处理器是不能移动第四条指令和第七条指令的。实际上,它们之间并没有依赖性。因此,Core微架构中则“大胆”的将第四条指令和第七条指令分别移动到第二和第三指令的并行位置,这种行为是基于一定的猜测的基础上的“投机”行为,如果猜测的对的话(几率在90%以上),完成所有的运算只要5个周期,相比之前的9个周期几乎快了一倍。
