怎么能将网站做的不简单,wordpress调用推荐文章代码,哪些网站可以做迁徙图,佳木斯做网站公司目录
一 ll和sc指令说明
二 ll和sc指令的实现
1 llbit寄存器
2 译码阶段
3 访存阶段
4 Load相关问题
5 流水线在取指阶段暂停 本章介绍两个比较特殊的加载存储指令ll和sc#xff0c;这两个指令的存在用于实现信号量机制。 信号量机制#xff1a;在多线程中为了保证某个…目录
一 ll和sc指令说明
二 ll和sc指令的实现
1 llbit寄存器
2 译码阶段
3 访存阶段
4 Load相关问题
5 流水线在取指阶段暂停 本章介绍两个比较特殊的加载存储指令ll和sc这两个指令的存在用于实现信号量机制。 信号量机制在多线程中为了保证某个正在运行的线程不被其他线程打扰需要遵循RMW操作序列这是一个规范过程读取修改返回并且此过程不能有任何打扰即为一个原子操作一定执行且不被打扰的操作为原子操作。 原子操作的实现方式需要基于信号量机制semaphore是一个信号量用来表示当前是否有进程在运行为1表示信号量使用中为0表示信号量空闲。进行原子操作前使用wait函数查询semaphore的值读取如果为1,则等待否则将其置为1,开始执行原子操作修改。操作结束后signal 函数将semaphore置为0返回这样其他线程就可以执行原子操作了。 MIPS32架构采用ll和sc这两个指令实现信号量机制具体步骤如下 ll指令同一般的加载指令一样从内存中加载一个字 但是有一点不同ll指令还会将处理器内部的一个链接状态位LLbit置为1,表明发生了一个链接加载操作并将链接加载的地址保存到一个特殊寄存器LLAddr中(这个寄存器在多处理器中有作用OpenMIPS是单处理器所以在OpenMIPS实现过程中并没有实现LLAddr寄存器)。ll指令执行完毕后会进行一定定的操作(如:修改加载得到的数据)然后执行sc指令。 执行sc指令时会对从II指令开始的RMW序列进行检查判断是否受到干扰实际就是判断LLbit是否为1,如果没有受到任何干扰LLbit 保持为1那么操作是原子的sc指令会对II指令加载数据的地址进行写回操作并设置一个通用寄存器的值为1,表示成功, 反之不进行写回操作并设置一个通用寄存器的值为0表示失败。 可以看到在这里LLbit就是一种信号量ll和sc指令搭配实现了一种RWM操作序列ll进行读取与修改sc指令进行返回操作。在这个过程中通过对信号量LLbit的修改实现了原子操作。
一 ll和sc指令说明 ll指令作用为:从内存中指定的加载地址处读取一个字节然后符号扩展至32位保存到地址为rt的通用寄存器中。并设置LLbit状态位为1.
sc指令作用为:如果RMW序列没有受到干扰也就是LLbit为1,那么将地址为rt的通用寄存器的值保存到内存中指定的存储地址处同时设置地址为rt的通用寄存器的值为1,设置LLbit为0。如果RMW序列受到了干扰也就是LLbit为0那么不修改内存同时设置地址为rt的通用寄存器的值为0。
二 ll和sc指令的实现
我们可以把LLbit当做一个寄存器模块ll指令在结束后会进行写操作sc指令会先读它然后再进行写rt寄存器。最后还会对LLbit寄存器进行写。LLbit寄存器同样放到回写阶段。 需要注意的是由于对LLbit寄存器的修改是在回写阶段最后的时钟上升沿进行的如果直接采用LLbit模块给出的LLbit寄存器的值可能不是正确的值因为此时处于回写阶段的上一条指令可能会需要修改LLbit寄存器这一问题在第6章添加HI、LO寄存器时也遇到过解决方法还是数据前推,将回写阶段指令对LLbit寄存器的操作信息是否进行写LLbit操作以及写入的值前推到访存阶段访存阶段依据这些情况确定正确的LLbit寄存器的值所以MEM/WB模块的输出信号wb_LLbit_we、wb_LLbit_value也要送到MEM模块就是用来解决数据相关问题的。
1 llbit寄存器
只需要对异常情况判断以及写使能如果有异常情况信号量更新为0。至于具体的异常处理在后面才会介绍。 2 译码阶段 ll指令加载内存地址写入寄存器需要写使能需要读base地址此外还需要修改LLbit的值也就是要对LLbit寄存器进行写操作。 sc指令从寄存器读数据写入内存最后还要修改LLbit寄存器和原通用寄存器要读两个寄存器一个base一个寄存器的值。 3 访存阶段
这是加载存储指令与特殊寄存器进行读写交互的地方为了避免数据相关操作需要先获取一下LLbit寄存器最新值即如果回写阶段也要写LLbit那就把写入的值给LLbit的最新值 ll指令需要读数据存储器一个字需要写LLbit寄存器1 sc指令因为是信号量机制所以要先检测信号量是否异常无异常为1时再进行操作需要写寄存器值到数据存储器需要写寄存器为1需要写LLbit寄存器为0 4 Load相关问题
加载操作需要写入值到寄存器如果下一条指令就需要使用此寄存器的值会不会有影响
答案是有的因为load加载操作在访存阶段才获取到写入寄存器的新值而下一条指令在译码阶段就已经获取了此寄存器的值显然这个值是落后的。如下图 那么是否可以使用数据前推来解决数据相关问题
答案是不可以的。原因主要是因为load是在访存阶段才获取到新值我们之前的数据数据相关问题在执行阶段就获取到了最新的值所以落后了一个阶段后就算把访存的值前推倒执行阶段而下一条指令早在前一个译码阶段就获取了。
那么该如何解决
既然相比之前的数据相关问题落后了一个阶段如果我们可以让第二条指令在译码阶段如果识别到当前指令与上一条指令存在load关系就暂停一次那么就相当于如下图 此时访存阶段获取到新值译码阶段正好需要取值满足数据前推的解决条件可以使用来解决问题。
5 流水线在取指阶段暂停
输出暂停信号之前还需要把上一条的指令回传过来好进行load相关的判定如果上一条指令是load指令且当前指令操作的寄存器就是load写入的寄存器那么就是load相关发生 具体实现
先判断上一条指令是不是加载指令 为什么SC指令也在这里呢因为sc指令在最后会回写寄存器也会更改寄存器的值。
接下来判断加载指令的目的地址是否和当前指令读的寄存器一样 如果满足load相关条件就请求流水线暂停 至此加载存储指令基本结束。