您的位置:首页 > 健康 > 养生 > 开通一个微信小程序_网站建设心得_百度网盘网页_南京百度

开通一个微信小程序_网站建设心得_百度网盘网页_南京百度

2025/1/10 10:07:58 来源:https://blog.csdn.net/jingyu_1/article/details/144812518  浏览:    关键词:开通一个微信小程序_网站建设心得_百度网盘网页_南京百度
开通一个微信小程序_网站建设心得_百度网盘网页_南京百度

计算机体系结构个人记录,总结动态流水线相关的内容
参考资料:
https://www.bilibili.com/video/BV1nQ4y157gt
https://blog.csdn.net/Programmer_jzm/article/details/135500350
https://blog.csdn.net/hanmo22357/article/details/127408447
https://blog.csdn.net/Programmer_jzm/article/details/135496230
《计算机体系结构:量化研究方法》

一、相关

  • 数据相关(真相关)
    指令 j 数据相关于指令 i,指令 j 使用了指令 i 产生的结果,或者指令 j 数据相关于指令 k,指令 k 数据相关于指令 i。
    数据相关的指令不能并行执行。
    寄存器的数据相关比较容易判断。
    存储器的数据相关不容易判断。
  • 名字相关
    逆相关:指令 j 写指令 i 所读的存储单元且 i 先执行,会导致流水线 WAR 相关。
    输出相关:指令 j 与指令 i 写同一个单元且 i 先执行,会导致流水线 WAW 相关。
    寄存器的名字相关可以通过寄存器重命名解决(彻底消除)。
    存储单元的重命名比较困难。

RISC 技术极大地简化了指令之间的相关性。

二、指令调度

  • 编译器静态调度
    编译器分析程序中的相关性,并针对目标流水线进行代码优化,以避免程序执行时由于相关引起阻塞。
    循环展开是一种经典的编译器优化方式,但是可能会是代码膨胀,例如可能会使得 cache 中放不下,从而 cache miss,导致性能反而降低。
    编译器可以在循环展开中分析相关性,可以使用软件重命名(换寄存器),从而可能进一步减少 stall。
  • 动态调度技术
    静态流水线的问题:
    在译码阶段把指令“隔开”解决问题,只要有一条指令停止,后面的指令就不能前进,类似于一种译码部件的结构相关。
    对编译器要求高,最好是编译器把相关指令隔开,有些信息在译码时难以确定。

三、动态调度思想

基本思想:前面指令的等待不影响后面指令的继续前进,把相关的解决尽量往后拖延
把译码分成两个阶段:发射 issue 和读操作数

  • 发射:指令译码,检查结构相关
  • 读操作数:如果操作数准备好就读数,否则等待(在哪等? 有序 -> 乱序)
  • 当一条指令在读操作数阶段等待时,后面指令的发射可以继续进行

乱序执行的基本做法:

  • 指令进入时有序的
  • 执行可以是乱序,只要没有相关就可执行,多条指令同时执行
  • 结束也是有序的(如何把乱序变有序? 乱序 -> 有序)

有序进入、乱序执行、有序退出
有一些早期 CPU 是乱序执行、乱序退出的,但现代的 CPU 一般要求有序退出

与静态调度相比:
有些编译无法检测、编译器更加简单、程序性能对机器依赖少

乱序执行中 WAW、WAR 冲突需要特别考虑:
WAW、WAR 名字相关,并不代表真正的数据相关,通过寄存器重命名,使用不同的物理寄存器来消除名字相关。
计分板算法没有寄存器重命名,无法消除 WAW、WAR 冲突。

四、计分板算法

更详细的内容可以参考 https://blog.csdn.net/Programmer_jzm/article/details/135496230
循序指令发射:一条指令在流水线中停顿,将不能处理后续指令,如果两条指令存在冒险,即使后面存在一些不相关的、不会停顿的指令,流水线也会停顿。

计分板算法,有多个功能部件,如果指令使用的是不同的功能部件,是能同时进入EXE阶段的
计分板算法一般一个 cycle 最多发射一条指令
Issue 阶段通过停顿整个流水线所有级解决 WAW 冲突
Read operands 通过监控源操作数是否可获得来判定这个指令能够执行,以解决 RAW 冲突,这只会造成单条指令的停顿,流水线还是会继续
Write result 阶段如果有数据需要写回,计分板会判断是否有先前的指令在读这个数据且还没读完,通过引入停顿的方式解决 WAR 冲突,这只会曹成单挑指令的停顿,流水线还是能继续
计分板算法包含三个部分:

  1. 指令状态
    指出该指令处于四个步骤(issue、read operands、execution complete、write result)中的哪一步
  2. 功能单元状态
    • Busy:指示该单元是否繁忙
    • Op:在此单元中执行的运算
    • Fi:目标寄存器
    • Fj、Fk:源寄存器编号
    • Qj、Qk:生成源寄存器 Fj、Fk 的功能单元
    • Rj、Rk:指示 Fj、Fk 已准备就绪但尚未读取的标记。在读取操作数后将其设置为“否”
  3. 寄存器结果状态
    如果一条活动指令以该寄存器为目标寄存器,则指出哪个功能单元将写入每个寄存器。只要没有想改寄存器写入的未完成指令,则将此字段设置为空。

五、Tomasulo 算法

主要思想在现代处理器中普遍使用
通过寄存器重命名来消除 WAR 和 WAW 相关

Tomasulo 算法增加了以下结构:

  1. 保留站(也叫发射队列,把有序变成乱序的地方,同时又是实现了寄存器重命名的地方)内容:
    • Busy
    • Op:具体操作
    • Vj、Vk:源操作数的值
    • Qj、Qk:保存没有准备好的源操作数保留站号(0 表示操作数已经准备好)
  2. 寄存器增加一个域
    • 结果状态域:空表示寄存器值可用,否则保存产生寄存器结果的保留站号(或者叫重命名映射表 RAT, Register Alias Table)
  3. 结果总线
    • 除了返回结果值外,还要送回产生该结果的保留站号

发射:把操作队列的指令根据操作类型送到保留站(如果有空),发射过程中读寄存器的值和结果状态域
执行:如果所需的操作数都准备好,则执行,否则侦听结果总线并接收结果总线的值
写回:把结果送到结果总线,释放保留站
通过动态调度缓解流水线阻塞
保留站:寄存器重命名+缓存源操作数,避免寄存器成为瓶颈,避免 WAW 与 WAR 阻塞
Tomasulo 缺点:硬件复杂性、结果总线成为性能瓶颈,多条结果总线增加硬件复杂度

六、动态流水线的例外处理

精确例外:在处理例外时,发生例外指令前面的所有指令都执行完,例外指令后面的所有指令都未执行

大多数现代的操作系统都要求精确例外

非精确例外的原因:在乱序执行时,前面的指令发生例外时,后面的指令已经执行完并修改了寄存器或存储单元

计分板和 Tomasulo 算法中都是非精确例外

硬件支持动态流水线的精确例外处理:
实现精确例外处理的一个办法是把后面指令对机器状态的修改延迟到前面指令都已执行完
可以用一些缓冲器来临时保存执行结果,当前面所有指令执行完后,再把保存在缓冲器中的结果写回到寄存器或存储器

  • 在流水线修改机器状态(执行或者写回阶段)时,写到缓冲器
  • 增加提交(commit)阶段,【把缓冲器的内容写到寄存器或存储器】
  • 提交阶段只有前面的指令都结束后才能进行
  • 有序提交:乱序执行,有序结束
  • 所用的缓冲器通常被称为 Reorder Buffer(ROB)

有序变无序 -> 保留站(发射队列、调度器)
无序变有序 -> Reorder Buffer
重命名寄存器:临时存储值(运算结果)
Reorder Buffer:临时存储指令
只有当 comiit 时,才能把临时结果写到寄存器或存储器,其余时候都要放到重命名寄存器
三个重要的微架构中的结构:保留站、重命名寄存器、Reorder Buffer

七、重排序缓存 Reorder Buffer

内容:目标地址(存数地址或者寄存器号)、值、操作类型
写回时写到 ROB,后面的指令可能从 ROB 中读操作数
使用 ROB 号作为重命名号(原来的保留站号),一条指令的结果寄存器被重命名为结果 ROB 号

  • 保留站重命名源寄存器号
  • ROB 重命名结果寄存器号

提交 commit 时把结果写回到寄存器或存储器

只要有一条指令没有提交,它就不会对寄存器或存储器的内容进行修改,在一条指令没有提交之前容易取消该指令
[图片]

结果写回到 ROB 中,不直接写到寄存器

拓展:
寄存器重命名可以独立的,这里的例子将它和 ROB 放在一起,前面的基础 Tomasulo 示例中将它和保留站放在一起。
现在的 CPU 寄存器重命名独立出来了。

发射:把操作队列的指令根据操作类型送到保留站(如果保留站和 ROB 有空),并在ROB中指定一项作为临时保存该指令结果之用;发射过程中读寄存器的值和结果状态域,如果结果状态域指出结果寄存器已被重命名到 ROB,则读 ROB
执行:如果所需的操作数都准备好,则执行,否则根据 ROB 号侦听结果总线并接收结果总线的值
写回:把结果送到结果总线,释放保留站;ROB根据结果总线修改相应项
提交:如果第一条指令的结果已经写回且没有发生例外,把该指令的结果从 ROB 写回到寄存器或存储器,释放 ROB 的相应项。如果队列头的指令发生了例外或是猜测错误的转移指令,清空操作队列以及 ROB 等。

八、动态流水线小结

有序进入、乱序执行、有序结束
主要结构:

  • 保留站(发射队列)把有序变乱序,临时存指令
  • 重命名寄存器用于保存未提交的临时结果,临时存数据
  • ROB 把乱序重新变成有序

乱序的能力和有段队列大小紧密相关

  • 现代高性能 CPU 一般都有 100 条以上指令在流水线中乱序执行

九、拓展:多发射数据通路

保留站组织:

  • 独立保留站:每个功能部件一个保留站
  • 分组保留站:多个功能部件共享保留站
  • 全局保留站:所有功能部件共享保留站
    [图片]

读取寄存器值的时机:

  • 保留站前读寄存器
  • 保留站后读寄存器
    [图片]

寄存器重命名技术:

  • 双重作用
    例外或转移猜测错误时取消后面操作
    解决 WAR 和 WAW 相关
  • 核心思想
    一个操作写寄存器时重命名到其他寄存器
    一个操作结束时再写到结构寄存器

重命名的方法:

  • 软件重命名
  • 重命名到保留站、发射队列、ROB
  • 建立物理寄存器到逻辑寄存器的映射【现在主流的方式】

硬件重命名的分类:

  • 重命名寄存器和结构体存起分开
  • 重命名寄存器和结构寄存器不分开

假设保留站前读寄存器

在这里插入图片描述


物理寄存器堆的重命名算法
在这里插入图片描述

假设保留站后读寄存器

译码阶段:

  • 把目标寄存器映射到一个空闲的物理寄存器
  • 为源寄存器根据依赖关系找到相应的物理寄存器号
  • 把重命名后的寄存器号写入保留站

发射阶段:

  • 判断所需的操作数是否已经准备好,或正在写回
  • 从物理寄存器或结果总线中读寄存器的值

执行阶段:

  • 执行结果根据目标物理寄存器号写回到物理寄存器
  • 不用写回到保留站

提交阶段:

  • 修改重命名表确认目标寄存器的重命名关系
  • 释放老的目标寄存器重命名关系

转义猜错或意外:

  • 修改重命名表取消后面的已经建立的重命名关系
  • 把状态为 MAPPED 或 WRITEBACK 的都置为 EMPTY
  • 确认状态为 COMMIT 的映射为相应逻辑寄存器的最新映射

核心是重命名表
现在使用最多的是【保留站后读操作数】、【物理寄存器堆】
保留站后读操作数可以减少一次源操作数拷贝(从寄存器到保留站)
物理寄存器堆可以减少一次结果操作数拷贝(从物理寄存器到结构寄存器)
多发射情况:
Alpha21264:取指 4 条,发射 6 条,写回 6 条,commit 11 条

最短的是 4 条,所以是 4 发射
微结构上的参数,CPU 单核的性能可以关注一下以下参数:
Reorder Buffer 的项数
保留站的项数(统一的项数、或者分组的项数、分功能的项数)
物理寄存器堆的大小(物理定点寄存器个数、物理浮点寄存器个数)

十、拓展:考虑在多核上的问题

访存相关的内容涉及到要和别的 cpu 核心同步,比如一个 load 用到之前的一个 store 的结果,此时 store 还没 commit,在这个 cpu 中可以通过类似 forward 的形式从 write buffer 中获取 store,别的 cpu 无法像该 cpu 中从 write buffer 中获取数据一样从这个 cpu 中读(太复杂),所以需要有存储一致性模型进行约定、规范
同步操作

存储一致性模型
现代处理器(arm的、intel的、龙芯的)基本都是弱一致性的,弱的程度不一样

  1. 顺序一致性:
    一条指令必须完全执行完才能执行下一条指令
  2. 处理机一致性模型:
    在任一 load 允许被执行之前,所有在同一处理机中先于这一 load 的取数操作均已完成
    在任一 store 允许被执行之前,所有在同一处理机中先于这一 store 的访存操作均已完成
  3. 弱一致性模型:
    把同步操作和普通访存操作区分开来,只在同步点维护一致性
    同步操作实现顺序一致性,冲突访问必须用同步操作保护
    同步操作的执行满足顺序一致性条件
    在任一普通访存操作允许被执行之前,所有在同一处理机中先于这一访存操作的同步操作都已完成
    在任一同步操作允许被执行之前,所有在同一处理机中先于这一同步操作的普通访存操作都已完成
  4. 释放一致性模型:
    把同步操作进一步分成获取操作 ACQUIRE 和释放操作 RELEASE
    冲突访问必须用 REL-> ACQ 对隔开
    同步操作的执行顺序满足顺序一致性(意味着 ACR、REL 相关指令不能被重排序)
    在任一普通访存操作允许被执行之前,所有在同一处理机中先于这一访存操作的 ACQUIRE 操作都已完成
    在任一 RELEASE 操作允许被执行之前,所有在同一处理机中先于这一 RELEASE 的普通访存操作都已完成
    一般情况下: [ACQ xx -> … -> REL xx],可以保证从 ACQ 到 REL 这一段代码在外界看来是原子的

存储一致性模型在时间上给出次序,cache 一致性说一个值如何传递到其他处理器的机制

Cache 一致性决定系统为维护一致性所做的具体动作

个人理解:内存一致性是一个高层的抽象模型,具体的实现需要依赖缓存一致性协议、内存屏障指令、以及处理器硬件机制的协同作用。

访存事件次序在微结构中的实现

指令在保留站中等待发射时检查并等待

  • 等到前面的所有指令都提交
  • Store 操作写到 cache、访存失效队列空
  • 同步操作如 sync、LL、SC 一般在发射时控制

Store 的操作一旦写到缓存或存储器中,就不容易撤销了,在 commit 阶段才真正写到缓存或主存中
Store Queue(存储队列):是一个硬件结构,用于暂存尚未提交 commit 到缓存或主存的写操作。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com