I-BTB
- 每个entry对应一条指令;
- IBTB相较于其他的结构,有最大的tag开销,因为每个entry都有tag域段;
- entry内部没有冗余信息,每个信息都是必须的,同时每个entry的内容都不会有重复;
- 每分配一个新的branch,都会替换掉原来的一个branch;(索引在相同的位置)
- 一般会设计成多个port,interleave的结构,保证一个cycle可以读出所有的entry;
R-BTB
- 每个entry保存的是对齐的一块region,i.e. 32B,64B,对应的是多个指令;
- 每个entry会有n个branch slots, 对应n个branch指令;
- 通过region aligned pc来访问每个entry,可以拿到如下信息:
- 有多少条连续的指令可以fetch,也就是通过一个BTB entry.可以得到多个fetch pc;
- 每个branch指令的type;
- 第一条跳转指令对应的target;
- 可以多条branch指令,使用一个TAG(同一个region,使用一个);
- 同样每个entry之间,没有相同的信息,也就是没有冗余;
- if there exists an entry tracking the block with a free branch slot, no other branch gets displaced;
- 访问RBTB的entry时,其确定的跳转地址由下面几个因素决定:
- 该entry中分支指令的跳转地址;(比如,一个 32B 区域entry有两个slot,分别缓存 0x4和 0x1C 处的branch信息)
- entry的结束地址;
- 访问pc的偏移地址:
- 例如,如果偏移地址是0,那么下一个取指地址可能是:0x4的tgt, 0x1c的tgt, 以及都不跳转,走到entry end的地址;
- 如果偏移地址是0x10, 那么下一个取指地址只可能是:0x1c的tgt, 以及不跳转,走到entry end的地址;
- 也就是说,必须将每个slot的offset和pc的offset进行比较,这会增加一些逻辑(IBTB/BBTB没有这个逻辑),可能会造成时序紧张;
- 还有个问题,如果region过小,为了解决多取指令的问题,
为了解决一条指令跨两个region的问题,BTB需要提供两个port(或者interleave), 才能满足该要求;
B-BTB
- 从第一个地址开始,要么找到跳转指令,则结束当前block, 要不就直到block满,结束当前block;
- which is a sequence of at most 𝐼 instructions (or bytes), 𝐵 of which can be observed taken before branches. So far always taken branches cause a block to end before 𝐼 instructions.
- 每个entry会有n个branch slots, 对应n个branch指令;
- 同R-BTB, 访问单个entry, 可以拿到多个预取指令的pc;
- 可以多条branch指令,使用一个TAG(同一个block, 也可以使用一个?把offset扩宽,使其能够指向下一条?或者tag保证两条fetchline的相同?);
- 如上图所示,在B-BTB的结构中,不同entry之间,会存在相同的指令,也就是会有overlap, 所以在大量entry的场景下,建议不要使用B-BTB,这样会浪费很多entry;
- 好处:B-BTB打通了fetchline的限制,可以尽可能的,在一次fetch的过程中,产生更多的可以读取的指令,而不会被fetchline的边界所打断;
- if there exists an entry tracking the block with a free branch slot, no other branch gets displaced;
Micro-BTB
- 可以理解为,也是一种I-BTB, 只是是一种变种,在相同的entry大小下,其可以存放多条分支指令的tag和target;
- 提出这种结构的原因时,工艺增长比较慢,指令越来越多,BTB越来越大,对面积和时序的要求都很高;
- 这种结构的核心是:
- 将branch本身的pc做hash, 原来56bit只能放一个tag, 现在可以放2个hash后的tag;
- 原来只能放一个target address, 现在hash后可以放两个,分别对应两条branch指令;
- 将BTB的索引做一些算法,尽量不要让太多的branch都索引到一个entry上,减少conflict;
- 这篇文章中,有两个观点比较有意思;
1. L1I的miss与BTB miss相比,谁带来的penaty更大?--BTB miss, 原因如下:
- L1I miss后,在decoupled的FE种,分支预测还是在继续工作的,这些请求会继续送到L1I, 参与后续读取ram, 判断的流水线,可以将future instruction的latency给隐藏掉;
- 而BTB miss之后,流水线要么被stall,要么流水线继续工作,但是是在错误的分支上;等到真正的结果计算出来以后,整条流水线会被flush掉;
- 整个过程,会消耗很多个cycle;
- 同时,flush之后,decode queue是空的,这中间也有一段时间,没有任何指令可以送给BE进行处理;
- 而且,BTB miss之后,需要重新开始从L1I取指,这个取指过程(从L1/L2/L3/DDR中取指令),在L1I miss的时候,也会经历;
- 综上,BTB miss带来的penalty更大;、
2. FTQ/Decode Q的深度,对处理器性能的影响;
- 先说结论:increasing the FTQ and decode queue size increases the branch resolution latency.
- 原因如下:
- 在decode阶段,每个cycle所能够decode的指令,或者说送给BE的指令,是固定的,如果queue size增加,则这条指令在queue中待的时间就越长;
- 这就会导致resolve branch会带来更长的时间;
- 同理,在FTQ/DQ中,存放了太多的指令,一旦预测错误,所有的指令都需要被flush;
- 同时,队列大小的增加,会导致BE中的分支指令个数增加,而多个分支指令间,可能存在资源竞争,乱序,仲裁等问题,导致分支指令发现mismatch的时间增加;