在x86处理器系统中,存储器指令大体可以分为F(reg, reg)[1],F(reg, mem)和F(mem, reg) 三大类。在这些指令中,第1个Operand为目标操作数也可以为源操作数,第2个Operand只能为源操作数。与LSU部件直接相关的指令为F(reg, mem)和F(mem, reg)。后一类指令的处理相对较为复杂,该类指令需要首先进行存储器读,进行某种运算后,再次进行存储器写,即Read-Modify-Write μop。在Opteron微架构中,浮点和SSE指令的存储器读写依然需要通过Integer指令流水,为简化起见,下文不再讨论浮点和SSE指令的存储器读写指令。

一条存储器指令的执行需要使用AGU,ALU和LSU三大部件。AGU,ALU将和LSU部件协调流水作业,最终完成一次存储器读写操作。L1 Cache的Load-Use Latency参数的计算是从存储器指令进入LSQ开始计算。为了实现指令流水的并发高速运转,在AGU和ALU中也具备多级流水结构。存储器指令在通过ALU,AGU与LSU部件的过程中存在相互依赖关系,如图4‑3所示。

我们分别讨论F(reg,mem)指令和F(mem, reg)指令的执行过程。在RS(Reservation Station)等待的F(reg, mem)指令,当所需的Operands Available后首先Launch到AGU部件,并在地址计算完毕后,将结果发送到LSU部件。但是存储器访问μop是同时进入到AGU和LSU部分中的,只有LSU需要等待AGU的计算结果。

在LSU部件从存储器子系统中获得最终数据之后,将其送给ALU,并最终完成指令的执行。F(mem, reg)指令的执行过程与此相近,只是需要在LSQ中经历两次等待过程,第1次是等待ALU计算的结果,第2次等待Store μop的commit将结果最终写入Cache。F(mem, reg)进行存储器读时的操作与F(reg, mem)一致。

AGU和ALU Pipeline的执行过程较易理解,本篇对此不做进一步的说明。Opteron LSU的设计使用Tag和Data总线分离的方式。Scheduler在监听Result Bus时,发现对应的Tag有效时即可启动LSU和ALU的μop,不必等待Data总线,通常情况下Tag bus上的数据先于Result Bus一个cycle,以Overlap不同的流水阶段。在Opteron微架构中,1个Cycle,可以Launch一个ALU和一个AGU微操作。如图4‑3所示,这两个操作显然没有对应关系。

LSU部件负责与其下的存储器子系统进行数据交互,也是图4‑3所示三大部件中最为复杂的一个部件。在Opteron微架构中,LSU由两个部件组成,分别是LS1和LS2。其中LS1中含有12个Entry,LS2中含有32个Entry,共44个Entry[6]。

LS1和LS2也被分别称为Pre-Cache和Post-Cache Load/Store Unit,绝大多人会认为LS1用于访问L1 Cache,而LS2用于访问L2 Cache。这一说法源自AMD的软件优化手册[73],这似乎是一个权威说法,也在某种程度上善意地误导着读者。这一说法非但并不准确,在某种程度上甚至是错误的。Opteron LSU的结构示意如图4‑4所示。

在Opteron微架构中,一条存储器读写指令在被Dispatch到Integer Scheduler的同时,也会被Dispatch到LS1的相应Entry中等待。LS1通过监听AGU的Tag总线获得必要的信息后,开始真正意义上的执行。这些必要的信息包括,LS1所需要的地址是否能够在下一拍有效,将使用哪一个AGU产生的地址。LS1使用Tag总线的信息虽然不能用于L1 Cache的Probe操作,却可以实现AGU和LSU的流水执行。

Opteron微架构分离Tag和Data总线是利用流水进行加速的技巧,将AGU的执行分解为两个步骤,以最大化AGU与LSU流水部件间的Overlap。除了AGU部件分离的Tag和Data总线,LSU和ALU也进行了这样的总线分离。

在LS1中的指令在下一拍从Data总线中获得地址后执行,由上文所述,Opteron微架构的L1 Cache具有两个端口,当所访问的数据间不发生冲突的前提下,LS1率先处理最先进入队列的两条存储器读写指令,并将其转交给L1 CacheController做进一步处理。

无论是存储器读还是存储器写操作,L1 CacheController都需要首先进行Probe操作。读操作发起的Cache Read Probe操作将带回数据。写操作发起的Cache Probe操作,也被称之为Probe-before-Write。进行这个Probe操作之前,需要准备好待写的Cache Block,Probe操作返回时将会带回数据,而当且仅当存储器写指令获得最终数据而且进行Commit操作之后,才能将数据真正写入。由于写入的数据在多数情况不能占满一个完整的Cache Block,此时需要和Probe操作带回的数据进行Merge后进行写入操作。

写操作的实现细节比上文描述的过程复杂得多。即便我们抛离了与Store Ordering相关的诸多和Memory Consistency的概念和各类Cache Write策略,没有考虑在Cache Write Hit时使用的Write-Through,Write-Back和Write-Once策略,没有考虑Cache Write Miss时使用的Write-Allocate,Write-Validate和Write-Around策略。

我们首先考虑在进行Write Probe操作之前,在Cache流水线准备好一个未使用的Cache Block,到从存储器子系统获得数据后真正写入数据的这段延时。我们首先关注这个刚刚准备好的Cache Block在此时使用的状态信息,似乎MOESIF这几个状态都无法准确描述此时的这条Cache Block所处的状态。

MOESIF这些状态位仅是Cache Controller所使用的简单得不能再简单的状态位,仅是一个Stable状态,是Cache Block诸多状态中一个子集。一个Cache Block中还含有其他状态位,更为复杂的处理Race Condition的Transient状态位。在Cache与Cache间的总线中包含着诸多Coherence Message和各类Bus Transaction。如果进一步考虑多级Cache的组成结构后,Cache ControllerFSM使用的状态位和流程迁移的复杂程度令人叹为观止。

其次我们需要考虑存储器写操作在等待最终Commitment时所带来的延时。如上文所述,如果存储器读指令的访问结构在LSQ中命中时,微架构将不会读取L1或者更高层次的Cache,从而充分利用了这个延时。这个延时可以带来的另外一个好处,由于后续的存储器读指令可能需要读取相同的Cache Block,此时也要进行Probe Cache操作。在这个延时中,这两个Probe操作可以合并,从而在一定程度上降低了总线的Traffic。这些优化手段提高了存储器读写指令的效率,也带来了较大的系统复杂度。

在Opteron LS1中的存储器读或者写操作,如果没有及时完成,例如存储器写指令没有及时地进行Commitment,将导致存储器写操作无法在LS1中完成,此外如果存储器读没有在L1 Cache中命中也无法及时完成时,这些在LS1中的指令都将进入LS2,从而为后续的存储器指令预留空间。这些预留可以为更多可能在L1 Cache Hit的存储器操作并发执行。从这个角度分析可以发现LS1主要用于Cache Hit的处理。

在LS2中的所有存储器读写指令,包括Load,Store和Load-Store指令将继续监听Cache Probe的结果,当发生Cache Miss时,需要将存储器读写请求转发给BUI(Bus InterfaceUnit)部件,BUI部件将根据需要从L2 Cache或者主存储器中获得最终数据。即LS2用于处理Cache Miss时,需要较长时间的存储器读写指令。

在Opteron微架构中,采用了Non-Blocking Cache的实现方式,为每一条Miss存储器请求添加了一个MAB Tag(Missed Address BufferTag)之后再发送给BUI部件,同时为这些Miss请求在LS2中设置了Fill Tag。当Probe操作的数据从L2 CacheController返回时,其MAB Tag将与在LS2中的Fill Tag进行比较,进一步确认数据是否有效,并将LS2中的存储器指令的状态从Miss更新为Hit。

Store指令将在LS2中停留更长的时间,直到该指令从流水线中按序退出后,才能将数据写入到存储器子系统中。当发生Misprediction或者Exception,微架构可以丢弃在LS2中的暂存的Store指令。只要Store指令没有离开LSU,都可以丢弃,当然这种丢弃是条件的,并不是随意丢弃。

在Opteron微架构中,L1和L2 CacheController将与LSU共同完成一次存储器读写操作。在L1和L2 Controller中含有各类Buffer,和连接这些Buffer的通路。一次存储器访问指令,在通过指令流水后,将首先到达LSU,并由LSU将其请求转发至L1和L2 CacheController,并由这些Cache Controller完成剩余的工作。

Cache Controller需要在保证Memory Consistency的前提下,将数据重新传递给LSU,完成一次存储器读写的全过程。在一个微架构中,Cache Controller是一个较为复杂的功能,由其管理的Cache流水线是整个微架构的精华。


[1] 许多论文书籍认为F(reg,reg)指令不属于存储器指令。

4.2 存储器读写指令的发射与执行2相关推荐

  1. 【计算机组成原理】实验4:存储器读写实验

    实验内容 一.实验原理 存储器是计算机的存储部件,用于存放程序和数据.存储器是计算机信息存储的核心,是计算机必不可少的部件之一,计算机就是按存放在存储器中的程序自动有序不间断地进行工作. 本系统从提高 ...

  2. ARM:特殊功能寄存器、Load/Store内存读写指令、栈操作指令

    1.特殊功能寄存器读写指令 msr -->>将普通寄存器中的数据写到特殊寄存器中 mrs -->>将特殊寄存器中的数据写到普通寄存器中 注:特殊寄存器 cpsr 的读写访问只能 ...

  3. 寄存器内存读写指令(二) —— 多寄存器读写 LDM / STM

    有的时候,CPU可能会遇到 a++; b++; c++,这个时候为了提升效率,CPU可能会一次将多个寄存器里的变量保存到内存中.这个时候之前介绍的 LDR / STR 指令虽然也能实现,但只能操作一个 ...

  4. Debug的T命令在执行修改寄存器SS 的指令时,下一条指令也紧接着被执行。

    为什么会这样呢?要想彻底说清楚这里面的来龙去脉,在这里还为时过早,因为这涉及我们在以后的课程中要深入研究的内容:中断机制,它是我们后半部分课程中的一个主题.现在我们只要知道这一点就可以了: Debug ...

  5. Java调用linux指令工具类,直接执行cmd,执行grep指令返回结果,执行sed追加指令,hdfs下载指令,获取文件行数

    Java调用linux指令工具类,直接执行cmd,执行grep指令返回结果,执行sed追加指令,hdfs下载指令,获取文件行数 问题背景 LinuxUtils工具类 Lyric:梦想挟带眼泪 问题背景 ...

  6. 软中断指令int $0x80的执行过程

    软中断指令int $0x80的执行过程 它是陷阱类(编程异常)事件,因此它与异常响应过程一样. 将IDTi(i=128)中段选择符(0x60,内核代码就是这个表项)所指GDT中的内核代码段描述符取出, ...

  7. DSP关于存储器读写、IO读写时序图的注意点

    这里的存储器图不涉及插入等待周期. IO设备的图可以自行减去插入等待周期,然后观察. 存储器读读写 存储器写写读 I/O设备读写操作

  8. 【微机原理作业】8086存储器读写实验

    一.作业要求 利用 2764 和 6264 在 8086 最小模式下扩展 16K ROM 和 16K RAM ,对其地址进行读写(注意数据的偶对齐). 将2764某一段数据读出并写入6264,详细展示 ...

  9. 存储器读写c语言程序,单片机IIC接口存储器AT24C04的读写和显示程序(详细注释)...

    //----------------------------------------------------------------- //        名称: I2C接口存储器AT24C04读写与 ...

  10. 计算机组成课程设计之二——微程序控制的存储器读写系统设计

    如果部分电路图显示不清楚可放大页面后查看 设计要求 课程设计平台为设计环境提供了容量为256×8的随机存储器.在此基础上,设计相应的外围电路和时序对随机存储器进行读写操作.结构框图如下图所示,设计完成 ...

最新文章

  1. Java 获取 Julian Day (Calendar)
  2. 猎八哥浅谈存储过程——数据库中的双刃剑
  3. Angular-cli生成组件修改css成less或sass
  4. oracle 从别的数据库获取数据 ,访问其他数据库
  5. 关于指针释放的小领悟
  6. lisp坐标一键生成_Grasshopper自动生成坡度标注
  7. 使用Spring Data JPA作为持久层框架
  8. python第五篇:Linux上将txt导入mysql
  9. Qtp10安装过程遇到的问题
  10. 全国信息流广告优化师交流群,不容错过!赶紧加入!
  11. MySQL学习笔记[学习资料来源于B站黑马测试]
  12. 绝对值线性化的两种方式
  13. 极速办公(PPT)如何添加删除线
  14. 计算机怎么取消用户密码,怎么取消电脑开机密码界面
  15. “好好说话,别伤人。”
  16. JPBC部分API说明
  17. txt电子书如何用安卓手机完美打开?
  18. Java面向对象05:创建对象的内存分析成员变量和局部变量的内存分析
  19. windows录屏_电脑上的录屏软件有哪些?不如试试这两个方法
  20. SQL——多表连接查询

热门文章

  1. ajax data=text,jQuery ajax dataType值为text json探索分享
  2. 问题 B: PIPI发工资(拓扑排序遍历)
  3. 大盘酝酿反弹中-可以短跑几天
  4. sql:mysql:函数:字符串函数
  5. nextcloud私有云盘搭建
  6. 猎头如何做大单,赚大钱?
  7. Appro DM36x IPNC 4.0 开发环境配置
  8. 0基础怎么画出好看的水彩画美术集水彩教程入门级教程
  9. win10 屏幕保护程序“在恢复时显示登录屏幕”灰色
  10. 学习 React.js 需要了解的一些概念