给别人做网站别人经营违法研究院网站建设方案

当前位置: 首页 > news >正文

给别人做网站别人经营违法,研究院网站建设方案,企业网站内容策划,企业网站如何找词总体架构 分支预测和指令缓存#xff0c;通过FTQ达到解耦的目的#xff1b;FTQ将请求送给ICache,进行取指#xff1b;取出的指令码通过预译码初步检查分支预测的错误并及时冲刷预测流水线#xff1b;检查后的指令送入指令缓冲并传给译码模块#xff0c;最终形成后端的指令… 总体架构 分支预测和指令缓存通过FTQ达到解耦的目的FTQ将请求送给ICache,进行取指取出的指令码通过预译码初步检查分支预测的错误并及时冲刷预测流水线检查后的指令送入指令缓冲并传给译码模块最终形成后端的指令供给 分支预测   分支预测单元采用一种多级混合预测的架构主要包括  下一行预测器Next Line Predictor以下简称 NLP 由uBTB组成提供无bubble的预测在预测请求的下一拍就能得到结果 精确预测器Accurate Predictor以下简称 APD 由 FTB、TAGE-SC、ITTAGE、RAS 组成其中FTB、TAGE、RAS 的延迟为 2 拍SC、ITTAGE 的延迟为 3 拍 一次预测会经历三个流水级每一个流水级都会产生新的预测内容。这些分布于不同流水级的预测器组成了一个覆盖预测器 (overriding predictor)。 相较于上一代雁栖湖架构分支预测器的最大区别在于预测块的定义方式。 南湖架构中BTB 被替换成了 FTB (Fetch Target Buffer)每一个 FTB 项都形成一个预测块。我们不仅对下一个块的起始地址做预测同时也对当前块的结束点做预测。 顶层逻辑 负责预测逻辑和流水线握手逻辑以及全局分支历史的管理。 与FTQ的交互 各级流水线都会连接FTQ当第一个预测流水线预测出了结果或者后续的流水线发现预测结果与之前的不一致和FTQ的握手vld会拉高将预测信息写入或者进行修改 全局分支历史管理 南湖架构实现了接近完全准确的全局分支历史 speculative update 每次预测都会根据预测块内部的分支指令个数以及预测方向计算新的全局历史并将其用在新的预测中覆盖逻辑中加入全局历史的比较 一旦位于后面的流水级推测更新后与之前的流水线结果不同时条件分支个数或者时执行的结果不同会flush流水线?重新开始预测预测后存储全局历史的副本 在预测结束后当次预测使用的全局历史会存储到 FTQ 中在误预测恢复时读出并送回 BPU 之所以说“接近”完全准确是因为 BPU 会忽略那些从未跳转的条件分支指令它们不会被记录在 FTB 中也就不会包含在分支历史里 下一行预测器 (NLP) 旨在用较小的存储开销提供一个无空泡的快速预测流。 它的功能主要由 uBTB 提供。 对于给定的起始地址 PCuBTB对从 PC 开始的一个预测块做出整体预测。 NLP 用分支历史和 PC 的低位异或索引存储表;从表中读出的内容直接提供了最精简的预测: 下一个预测块的起始地址 nextAddr;这个预测块是否发生分支指令跳转 taken;跳转指令相对起始地址的偏移 cfiOffset;是否在条件分支跳转 takenOnBr;块内包含分支指令的数目 brNumOH;另外还提供分支指令的相关信息以更新分支历史;我们摒弃了 tag 匹配的做法这会带来一个问题: 在有 tag 匹配的情况下如果一个预测块没有命中会将下一个预测块的 PC 置为当前 PC 加预测宽度;通常为了避免浪费如果在预测块中没有分支指令则训练时不会写入 uBTB。在这个前提下如果没有 tag 匹配机制则很容易把没有分支指令在 tag 匹配机制下不命中的预测块预测为另一个跳转的块。 针对这种情况我们引入了另一种预测机制对当前 PC 是否可能存在有效的分支指令进行预测这个预测机制的存储结构由取指 PC 直接索引它的查询结果表示了该取指 PC 是否被写入过。在它指示该 PC 没被写入过的时候会把下一个 PC 预测为当前 PC 加预测宽度。 精确预测器 (APD) 为提高总体预测准确率减少预测错误带来的流水线冲刷南湖架构实现了延迟更高同时也更为精确的预测机制。 精确预测器包括取指目标缓冲 FTB、条件分支方向预测器 TAGE-SC、间接跳转预测器 ITTAGE 和返回地址栈 RAS。 FTB FTB 是 APD 的核心。APD 的其他预测部件所作出的预测全部依赖于 FTB 提供的信息。FTB 除了提供预测块内分支指令的信息之外还提供预测块的结束地址。对于 FTB 来说FTB 项的生成策略至关重要。记 FTB 项的起始地址为 start结束地址为 end具体策略如下 FTB 项由 start 索引start 在预测流水线中生成实际上start 基本遵循如下原则之一 start 是上一个预测块的 endstart 是来自 BPU 外部的重定向的目标地址FTB项内最多记录两条分支指令其中第一条一定是条件分支end 一定满足三种条件之一 end - start  预测宽度end 是从 start 开始的预测宽度范围内第三条分支指令的 PCend 是一条无条件跳转分支的下一条指令的 PC同时它在从 start 开始的预测宽度范围内注意这种训练策略下同一条分支指令可能存在于多个 FTB 项内。和论文中的实现一样我们只存储结束地址的低位而高位用起始地址的高位拼接得到论文链接A ScalableFront-EndArchitectureforFastInstructionDeliveryhttps://download.csdn.net/download/zhangshangjie1/89865369和 AMD的做法相似我们还对 FTB 项中的条件分支指令记录“总是跳转”位 该位在第一次遇到该条件分支跳转时置 1在它值为 1 的时候该条件分支的方向总是预测为跳转也不用它的结果训练条件分支方向预测器当该条件分支遇到一次执行结果为不跳转的时候将该位置 0之后它的方向由条件分支方向预测器预测。 TAGE-SC TAGE-SC 是南湖架构条件分支的主预测器它的大致逻辑继承自上一代雁栖湖架构的 TAGE-SC-L。 目前的实现中TAGE 的延迟是 2 拍SC 的延迟是 3 拍。 TAGE 利用历史长度呈几何级数增加的多个预测表可以挖掘极长的分支历史信息。它的基本逻辑如上图所示。 由一个基预测表和多个历史表组成基预测表用 PC 索引而历史表用 PC 和一定长度的分支历史折叠后的结果异或索引不同历史表使用的分支历史长度呈几何级数关系。在预测时还会用 PC 和每个历史表对应的分支历史的另一种折叠结果异或计算 tag与表中读出的 tag 进行匹配 如果匹配成功则该表命中最终的结果取决于命中的历史长度最长的预测表的结果在南湖架构中每次预测最多同时预测 2 条条件分支指令。 在访问 TAGE 的各个历史表时用预测块的起始地址作为 PC同时取出两个预测结果它们所用的分支历史也是相同的。 TAGE还有一些其他的特性如备选预测逻辑useful域段sc校正等功能这些功能参考TAGE predictor ITTAGE RISC-V 指令集中 jalr 指令支持以寄存器取值加一立即数的方式指定无条件跳转指令目标地址。不同于在指令中直接编码跳转偏移量的 jal 指令jalr 的跳转地址需要借助寄存器访问间接获取因而被称为间接跳转指令。由于寄存器的值可变于是相同 jalr 指令的跳转地址可能很多样所以 FTB 记录固定地址的机制难于准确预测这种指令的目标地址。在香山处理器中jalr 指令的预测机制体现为 FTBRAS 与 ITTAGE 的协作。 FTB 会记载 jalr 指令的最近一次跳转地址部分 jalr 指令的跳转地址相对固定仅靠 FTB 就足以达到很高的预测准确率函数返回是 jalr 指令中较为常见的应用场景它和函数调用指令有着显著的配对性可以使用具有栈结构的 RAS 进行预测不符合以上特征的 jalr 指令交由 ITTAGE 预测。 ITTAGE是一种准确率很高的间接跳转预测器它的基本结构如上图所示。 ITTAGE 在 TAGE 的主要区别在于每个表项在 TAGE 表项的基础上加入了所预测的跳转地址。由于每个 FTB 项仅存储至多一条间接跳转指令信息ITTAGE 预测器每周期也最多预测一条间接跳转指令的目标地址。ITTAGE 和 TAGE 的内部逻辑基本相同此处不再重复。 RAS RAS 是一个寄存器堆实现的栈存储结构 它对 call 指令的下一条指令的地址进行记录在 FTB 认为预测块会在 call 指令跳转时压栈并在 FTB 认为预测块在 ret 指令跳转时弹出。每一项包含一个地址和一个计数器 当重复压栈同一个地址时栈指针不变计数器加一用于处理程序中递归调用的情况。每次预测后栈顶项和栈指针都会存入 FTQ 的存储结构用于误预测时恢复。 预测器的训练 总的来说为防止错误执行路径对预测器内容的污染各部分预测器在预测块的所有指令提交后进行训练。 它们的训练内容来自自身的预测信息和预测块中指令的译码结果和执行结果它们会被从 FTQ 中读出并送回 BPU。其中 自身的预测信息会在预测后打包传进 FTQ 中存储指令的译码结果来自 IFU 的预译码模块在取到指令后写回 FTQ而执行结果来自各个执行单元。 在 BPU 收到来自其外部的重定向请求时会把曾进行过推测更新的元素全局历史、RAS 栈顶项等进行恢复。 预测块 分支预测单元 (BPU) 每次给取指目标队列 (FTQ) 的请求基本单位它描述了一个取指请求的范围以及其中分支指令的情况 预测宽度 每次预测提供给取指单元的最大指令流宽度在南湖架构中与取指宽度相同都为 32 字节。当 FTB 预测未命中时目标地址默认为当前地址和预测宽度相加 覆盖预测器 一种多个不同延迟的预测器的组织形式延迟大的、相对更准确的预测器被放在后面的流水级其产生的预测结果会与前面的预测器进行比较如果不同则会冲刷流水线整体预测结果以最准确的预测器为准 全局分支历史 指令流中所有条件分支指令的执行结果序列每一条分支指令的执行结果作为一位0/1存在于全局分支历史中一般以移位寄存器的方式实现 备选预测 TAGE 类预测器一种优化当对长历史预测结果信心不足时选择次长历史下的命中结果作为最终预测可提升整体预测正确率 取指目标队列 (FTQ) FTQ 是分支预测和取指单元之间的缓冲队列 主要职能是暂存 BPU 预测的取指目标并根据这些取指目标给 IFU 发送取指请求。另一重要职能是暂存 BPU 各个预测器的预测信息在指令提交后把这些信息送回 BPU 用作预测器的训练因此它需要维护指令从预测到提交的完整的生命周期。由于后端存储 PC 的开销较大当后端需要指令 PC 的时候会到 FTQ 读取。由于 BPU 基本无阻塞它经常能走到 IFU 的前面于是 BPU 提供的这些还没发到 IFU 的取指请求就可以用作指令预取FTQ 中实现了这部分逻辑直接给指令缓存发送预取请求 FTQ 是一个队列结构但队列中每一项的内容是根据其自身特点存储在不同的存储结构中的。这些存储结构主要包括以下几种 ftq_pc_mem: 寄存器堆实现存储与指令地址相关的信息包括如下的域 startAddr 预测块起始地址nextLineAddr 预测块下一个缓存行的起始地址isNextMask 预测块每一条可能的指令起始位置是否在按预测宽度对齐的下一个区域内fallThruError 预测出的下一个顺序取指地址是否存在错误 ftq_pd_mem: 寄存器堆实现存储取指单元返回的预测块内的各条指令的译码信息包括如下的域 brMask 每条指令是否是条件分支指令jmpInfo 预测块末尾无条件跳转指令的信息包括它是否存在、是 jal 还是 jalr、是否是 call 或 ret 指令jmpOffset 预测块末尾无条件跳转指令的位置jalTarget 预测块末尾 jal 的跳转地址rvcMask 每条指令是否是压缩指令 ftq_redirect_sram: SRAM 实现存储那些在重定向时需要恢复的预测信息主要包括和 RAS 和分支历史相关的信息 ftq_meta_1r_sram: SRAM 实现存储其余的 BPU 预测信息 ftb_entry_mem: 寄存器堆实现存储预测时 FTB 项的必要信息用于提交后训练新的 FTB 项 指令在 FTQ 中的生存周期 指令以预测块为单位从 BPU 预测后便送进 FTQ直到指令所在的预测块中的所有指令全部在后端提交完成FTQ 才会在存储结构中完全释放该预测块所对应的项。 预测块从 BPU 发出进入 FTQbpuPtr 指针加一初始化对应 FTQ 项的各种状态把各种预测信息写入存储结构如果预测块来自 BPU 覆盖预测逻辑则恢复 bpuPtr 和 ifuPtrFTQ 向 IFU 发出取指请求ifuPtr 指针加一等待预译码信息写回IFU 写回预译码信息ifuWbPtr 指针加一如果预译码检测出了预测错误则给 BPU 发送相应的重定向请求恢复 bpuPtr 和 ifuPtr指令进入后端执行如果后端检测出了误预测则通知 FTQ给 IFU 和 BPU 发送重定向请求恢复 bpuPtr、ifuPtr 和 ifuWbPtr指令在后端提交通知 FTQ等 FTQ 项中所有的有效指令都已提交commPtr 指针加一从存储结构中读出相应的信息送给 BPU 进行训练 预测块 n 内指令的生存周期会涉及到 FTQ 中的 bpuPtr、ifuPtr、ifuWbPtr 和 commPtr 四个指针当 bpuPtr 开始指向 n1 时预测块内的指令进入生存周期当 commPtr 指向 n1 后预测块内的指令完成生存周期。 取指令单元Instruction Fetch Unit 南湖架构的 IFU 采用了 4 级流水线的结构相较于雁栖湖版本 IFU 的设计做了非常大的简化这得益于采用分支预测 - 指令缓存解耦的取指令架构。 一个取指令请求从 FTQ 发出之后在 IFU 中经历了下面几个阶段 从 FTQ 发送过来的取指令请求包含了一个 32 bytes 指令码 称为一个指令块 的起始地址和下一个跳转目标的地址在 IFU0 阶段同时发送请求给 IFU 流水线和 ICache 模块。IF1 阶段会做一些简单计算例如这个指令块里每个 2 bytes 即每一条可能的指令的 PC 。IF2 阶段等到指令缓存返回最多两个 cache line 的数据因为可能存在这个 指令块 跨行 的情况之后第一步先做指令切分将在取指令地址之外的指令码抛弃得到有效范围的指令码。送入预译码器进行预译码同时将 16 bits 的压缩指令扩展为 32 bits 的指令。IF3 阶段首先会将预译码结果送到 分支预测检查器 里发现错误就会在下一拍刷新 IFU 流水线并把信息发送给 FTQ 刷新预测器并重新取指令。未发现错误的缓存在指令缓冲队列IBuffer里等待译码。IF3 阶段还会根据地址翻译的结果向指令 MMIO 模块发起取指令请求同时转变为 MMIO 取指令模式指令一条一条顺序执行。IFU 控制逻辑还需要 处理半条 RVI 指令 的情况。 预译码 预译码器将经过切分的 16 个 16 bits 指令码进行译码得到部分指令信息 是否是跳转指令跳转指令类型以及是否是压缩指令等对于跳转指令还会计算它的目标地址。 主要是为了给 分支预测检查器  提供指令信息正确的目标地址以及及时更新预测器中的指令信息 另一方面预译码器也会将压缩指令如果这个指令块里有的话扩展为 32 bits 的长指令以便于后续简化译码逻辑。 分支预测检查 分支预测检查器在拿到指令的预译码信息之后主要针对以下几个错误检查 jump 指令预测不跳转的错误针对 jal 和 ret 这两种种必定跳转的指令检查如果这个块的 有效指令范围 内有这两种指令且预测为不跳转则视为预测错误。非跳转指令的预测错误如果预测为跳转的指令不在有效指令范围内或者在有效指令范围内但是不是一条跳转指令则视为预测错误。目标地址错误对于可以通过指令码知道目标地址的跳转指令除了 jalr 之外的跳转指令如果在有效指令范围内且预测跳转并且跳转目标地址和正确地址不匹配则视为预测错误。 在发现错误后分支预测检查器挑选出指令顺序最靠前的预测错误指令把错误信息错误指令在块里的位置、指令预译码信息、正确的目标地址传递给 FTQ 同时清空 IFU 流水线。IFU 等待 FTQ 重新发取指令请求。 跨行指令处理Cross-line Fetch         由于我们的指令块包括了 32 bytes 的指令码相当于半个 cache line64 Bytes的大小如果这个块的起始地址在后半个 cache line 里那么完全有可能发生块的范围跨过两个 cache line 的情况         因此在指令缓存支持一次取两个 cache line 以保证这种情况下的指令吞吐。具体做法是当 FTQ 发现块的起始地址在后半个 cache line 里就发起对指令缓存两个相邻 cache line 的请求。 有效指令范围 一个取指令块的有效范围由 FTQ 给出的起始地址和跳转指令的 index如果有跳转的话共同确定如果这个块没有跳转指令则默认指令有效范围为起始地址开始的 256 bits。 有效指令范围可能被 IFU 的检查重新确定主要包括 分支预测检查发现有未预测跳转的 jal 和 ret 指令时需要重新将有效指令范围缩短到第一条这样的跳转指令前一个块有半条 RVI 的情况紧随其后的这个块的第一个 16 bits 不在有效指令范围内。MMIO 请求的块的指令有效范围只有 32 bits MMIO 取指令 在 IF3 阶段如果 ITLB 发现这个地址是 MMIO 空间的IFU 就启动 MMIO 取指令模式 向指令 MMIO 模块发送请求指令 MMIO 模块向 MMIO 总线发送 Get 请求 64 bits 的数据等待总线返回后根据 IFU 的请求地址对数据进行裁剪返回指令码。IFU 将指令码进行扩展之后发送给指令缓冲队列。同时IFU 阻塞流水线侦听 ROB 的 commit 信号直到指令执行完后发送前端重定向取下一条指令。 MMIO 请求每次只取一条指令因此在这种模式下处理器的指令执行速度会变得非常慢。 半条 RVI 指令的处理 当一个指令块在 IF3 阶段发现它的最后 2 bytes 是一条 RVI 指令的前半部分时我们把这条 RVI 指令算在这个块里同时我们取两个 cache line 的机制保证后半部分是一定可以被取到的因此我们只需要在发生这种情况的时候置一个标识位当下一个块来的时候把第一个 2 bytes 排除在指令的有效范围之外即可。 指令缓存Instruction Cache 缓存部分不做过多描述 译码单元 (Decode Unit) 基本功能 指令从指令缓存中取出送进指令缓冲队列中暂存然后以每周期 6 条的的速度送入译码单元译码再传给下一个流水级。 指令融合 (Instruction Fusion) 译码单元支持了一些指令的融合在 FusionDecoder 模块中会基于连续两条指令的 32bit 数据完成指令融合。对非连续的两条指令目前香山没有支持指令融合。 目前香山支持如下情况的指令融合 clear upper 32 bits / get lower 32 bits: slli r1, r0, 32  srli r1, r1, 32clear upper 48 bits / get lower 16 bits: slli r1, r0, 48  srli r1, r1, 48clear upper 48 bits / get lower 16 bits: slliw r1, r0, 16  srliw r1, r1, 16sign-extend a 16-bit number: slliw r1, r0, 16  sraiw r1, r1, 16shift left by one and add: slli r1, r0, 1  add r1, r1, r2shift left by two and add: slli r1, r0, 2  add r1, r1, r2shift left by three and add: slli r1, r0, 3  add r1, r1, r2shift zero-extended word left by one: slli r1, r0, 32  srli r1, r0, 31shift zero-extended word left by two: slli r1, r0, 32  srli r1, r0, 30shift zero-extended word left by three: slli r1, r0, 32  srli r1, r0, 29get the second byte: srli r1, r0, 8  andi r1, r1, 255shift left by four and add: slli r1, r0, 4  add r1, r1, r2shift right by 29 and add: srli r1, r0, 29  add r1, r1, r2shift right by 30 and add: srli r1, r0, 30  add r1, r1, r2shift right by 31 and add: srli r1, r0, 31  add r1, r1, r2shift right by 32 and add: srli r1, r0, 32  add r1, r1, r2add one if odd, otherwise unchanged: andi r1, r0, 1  add r1, r1, r2add one if odd (in word format), otherwise unchanged: andi r1, r0, 1  addw r1, r1, r2addw and extract its lower 8 bits (fused into addwbyte)addw and extract its lower 1 bit (fused into addwbit)addw and zext.h (fused into addwzexth)addw and sext.h (fused into addwsexth)logic operation and extract its LSBlogic operation and extract its lower 16 bitsOR(Cat(src1(63, 8), 0.U(8.W)), src2)mul 7-bit data with 32-bit data