代码锁存 RAM 、Cache

代码锁存   :   将重要使用频率高的代码锁存到RAM甚至Cache中,提高CPU的访问速度,加快程序运行。

RAM相比众所周知,这里主要先总结介绍和学习一下Cache的原理和设计结构。

---------------------------------------------------------------------------------------------------------

Cache:

*首先介绍一下cache发发展背景和趋势:

     虽然CPU主频的提升会带动系统性能的改善,但系统性能的提高不仅仅取决于CPU,还与系统架构、指令结构、信息在各个部件之间的传送速度及存储部件的存取速度等因素有关,特别是与CPU/内存之间的存取速度有关。 
  若CPU工作速度较高,但内存存取速度相对较低,则造成CPU等待,降低处理速度,浪费CPU的能力。 
  如何减少CPU与内存之间的速度差异?有4种办法: 
               一种是在基本总线周期中插入等待,但这样会浪费CPU的能力。 
      另一种方法是采用存取时间较快的SRAM作存储器,这样虽然解决了CPU与存储器间速度不匹配的问题,但却大幅提升了系统成本。 
      第三种方法是在慢速的DRAM和快速CPU之间插入一速度较快、容量较小的SRAM,起到缓冲作用;使CPU既可以以较快速度存取SRAM中的数据,又不使系统成本上升过高,这就是Cache法。 
      再有一种方法,采用新型存储器。 

  目前,一般采用第三种方法。它是PC系统在不大增加成本的前提下,使性能提升的一个非常有效的技术。 

------------------------------

*Cache的工作原理:

  Cache的工作原理是基于程序访问的局部性。 

  对大量典型程序运行情况的分析结果表明,在一个较短的时间间隔内,由程序产生的地址往往集中在存储器逻辑地址空间的很小范围内。指令地址的分布本来就是连续的,再加上循环程序段和子程序段要重复执行多次。因此,对这些地址的访问就自然地具有时间上集中分布的倾向。 

  数据分布的这种集中倾向不如指令明显,但对数组的存储和访问以及工作单元的选择都可以使存储器地址相对集中。这种对局部范围的存储器地址频繁访问,而对此范围以外的地址则访问甚少的现象,就称为程序访问的局部性。 

  根据程序的局部性原理,可以在主存和CPU通用寄存器之间设置一个高速的容量相对较小的存储器,把正在执行的指令地址附近的一部分指令或数据从主存调入这个存储器,供CPU在一段时间内使用。这对提高程序的运行速度有很大的作用。这个介于主存和CPU之间的高速小容量存储器称作高速缓冲存储器(Cache)。  

  操作系统正是依据此原理,不断地将与当前指令集相关联的一个不太大的后继指令集从内存读到Cache,然后再与CPU高速传送,从而达到速度匹配。CPU对存储器进行数据请求时,通常先访问Cache。由于局部性原理不能保证所请求的数据百分之百地在Cache中,这里便存在一个命中率。即CPU在任一时刻从Cache中可靠获取数据的几率。命中率越高,正确获取数据的可靠性就越大。一般来说,Cache的存储容量比主存的容量小得多,但不能太小,太小会使命中率太低;也没有必要过大,过大不仅会增加成本,而且当容量超过一定值后,命中率随容量的增加将不会有明显地增长。 

  只要Cache的空间与主存空间在一定范围内保持适当比例的映射关系,Cache的命中率还是相当高的。 一般规定Cache与内存的空间比为4:1000,即128kB Cache可映射32MB内存;256kB Cache可映射64MB内存。在这种情况下,命中率都在90%以上。至于没有命中的数据,CPU只好直接从内存获取。获取的同时,也把它拷进Cache,以备下次访问。

----------------------------------------------------------------------------------------------------------------

 当CPU需要数据时,首先到cache内部去寻找,如果找到了,则称为命中了(cache hit),如果没有找到,则称为丢失(cache miss),这时CPU必须到内存去读取数据,并且将其保存在cache中以备后用。

*Cache的基本结构 


————————————————————————————————————————————————————

Cache的组织结构


* 参见回答:https://www.zhihu.com/question/24612442/answer/53107450   (用心阁)*

————————————————————————————————————————————

i-cache和d-cache区别:


    一方面是cache的行为。Icache大多都是顺序取指,碰到分支指令也会跳转,而Dcache访问的模式变化比较大。
 指令只有读和refill没有写,而数据有读也有写。最重要的是冯氏的结构是指令和数据分离。I和D在一起只有相互干扰。
    另一个方面就是,物理设计上考虑: 一个union的cache,同时需要数据和指令的访问,端口上是很难实现的。 
 所以一般在流水线的主干上,都是采用分离的icache和dcache。非主干的L2 cache,从容量的角度考虑采用union的方式。

从微处理器架构的角度来说,所谓的Cache包括了两部分:Cache控制器和Cache存储器。  
ICache 只是读出指令,控制上比 DCache 要简单许多。

Cache存储器其一般实现方式主要有三种,分别是全相联,直接映射和组相联。全相联最灵活但是实现比较复杂。直接映射比较容易实现,但是可能产生快速抖动。组相联则是前两者的一个折衷。

DCache控制器在整个DCache中处于非常重要的地位,它控制了整个DCache所要进行的操作,同时会在发生缺失时采取相应的对策。其主要功能如下:

1) 反馈给微处理器读取 DCache 的信息,包括 DCache 的命中或者缺失等信息。如果发生缺失,可能会要求流水线发生阻塞。
2) 如果发生缺失,需要从下一级存储单元寻找相应的地址中的内容,并将内容载入到 DCache 中。
3) 控制读写操作。如果是读操作,则需要为下一级的操作提供相应的数据。如果是写操作,则需要将数据写入到相应的地址中去。
为了完成上述的功能,整个 DCache 控制器被分为三个部分,分别为用来判断命中还是缺失的判断部分和用来执行发生缺失时一些相应操作的有限状态机部分以及正常读写的控制部分。其中有限状态机部分中还包括了两个存储块,分别是为了实现 LRU (least recently used)算法的LRU 数据块和为了判断存储的数据有没有被改写过的 Dirty数据块

Cache的读与写

读操作

本设计所采用的读操作的方式是将标签域 (Tag) 中的内容和数据域 (Data) 中的内容同时读出,然后再将 Tag 的内容与地址高端进行比较。如果相等,则说明 DCache 命中,读出的 Data 的内容正是给出的地址中的内容。如果不相等,则说明发生了 DCache 读缺失,需要进行缺失处理。在不发生缺失的情况下,一次读操作可以在一个 Clock 周期内完成。这非常符合流水线的特性。
如果发生读缺失, DCache FSM 会首先查看 LRU 块,确定两路数据存储中具有同一索引的两个行中哪一行将会被替换出去。然后 FSM 会查看 Dirty 块,确定是否需要将行中的内容更新到主存。如果需要,则将之前读出的数据写入到主存,然后将主存中的数据读出,放到数据总线上,供流水线的下一级使用。如果不需要,则直接读取主存中相应地址的数据并放到数据总线上,供下一级使用。这些操作完成之后 FSM 会通知微处理器停止阻塞流水线,这样在下一个时钟周期微处理器又会正常运行。

 写操作

写操作一般有两种方式分别是写通过 (Write-through) 方式和写回 (Write-back)方式
写通过方式支持改写 Cache 中的内容,但是不允许 Cache 和主存内容不一致,因此,对在对 Cache 进行写操作时,对主存也要进行写操作。这会延长写操作的时间。
写回方式则是对相应的 Cache 进行写操作,但是并不立即对主存进行写操作,这能有效的减少访问主存的延迟。但是这种方式的实现比较复杂,因为 Cache 和主存的内容存在不一致性。
写操作分两步进行,首先需要读取标签域 (Tag)  和数据域 (Data) 中的内容, 然后 Tag 的内容与地址高端进行比较。如果相等,则说明 DCache 命中,需要写入数据的地址存在,可以将数据写入 DCache 中。同时由于写入的数据只有 32 位,而读出的数据有 128 位,需要通过地址总线的低位来进行选择需要写入的字段。如果 Tag 不相等,则说明发生了 DCache 写缺失,需要进行缺失处理。
在不发生缺失的情况下,一次写操作需要两个 Clock 周期来完成,这不符合流水线的要求,若采用了流水线式的写入方式,在微处理器和 DCache 之间加入了一级写缓存。在读取 DCache 的标签和数据的内容的同时,将数据写入写缓存。这样就能够使得写入操作以流水线的方式进行,可以满足流水线微处理器的要求。
当发生写缺失时,同样 FSM 会先查看 LRU 块,确定哪一行需要从两路数据存储块中删除,然后再查看需要从 Dcache 中删除的行是否为“脏”。如果是“脏”行,则将之前从 DCache 中读出的数据写入到主存,并将主存的数据读出,并连同之前存入写缓存中的数据,准备写入到 DCache 中。如果行“干净”,则直接读出主存中的数据,并和写缓存的数据做好写入 DCache 的准备。完成之后 FSM 会通知微处理器停止阻塞流水线,这样在下一个时钟周期微处理器又会正常运行,同时将数据写入。
注:
          1、DMA 通常负责外设与 RAM 的通信,是不经过 CPU 的,当 DMA 修改 RAM 中的数据时,CPU 是不知道的。(单核CPU中存在唯一关键问题)





参考:

http://www.cnblogs.com/waytofall/p/3998854.html  (CPU 与 Cache)

http://www.jianshu.com/p/061a5d66ea20    (Cache结构)

http://blog.csdn.net/zdl1016/article/details/8882092  (概述)

http://blog.chinaunix.net/uid-24517893-id-334964.html (可能的不一致性)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【实验题目】 在RAM执行程序代码 【实验目的】 掌握片外RAM扩展方法(重点是硬件接法,而程序操作很简单)。 弄清楚什么是“哈佛存储结构”和“冯·诺依曼存储结构”。 【硬件接法】 P1.2接交流蜂鸣器。 请认真参考硬件电路图RAM的接法。RAM映射到地址“0x8000~0xBFFF”,共16KB。 【实验原理】 8051单片机本来是“哈佛存储结构”,程序ROM和片外数据RAM位于完全分开的存储空间。/WR和/RD信号用于访问片外数据RAM。当使用片外程序ROM时,/PSEN管脚负责读取程序代码或固定数表。通常ROM不可写,所以未安排ROM的写信号。ROM和RAM共用地址和数据总线,但读写选通信号是分开的,所以在逻辑上分属两个不同的64KB空间,总共128KB。另外片内数据RAM和SFR空间又与前两者有别,是独立编址的。在软件上,访问不同的存储空间采用不同的指令,如“MOVX A,@DPTR”、“MOVC A,@A+DPTR”、“MOV A,@Ri”等。 注意,/PSEN和/RD可以经过“与门”后再接到RAM的/OE。这样,代码和数据都位于相同的地址空间,在RAM也可以跑程序,用“MOVC”和“MOVX”指令都能访问RAM的存储单元。如果把程序代码加载到片外RAM,然后用“LJMP”指令跳转过去就能在RAM执行程序代码。 【说明:片内Flash的引导程序】 这是一个比较复杂的程序,其还牵涉到了C51嵌入汇编的用法。对大多数初学者来说,只要了解其工作过程即可,不必深究。如果您确实对其感兴趣,请自行仔细研究。 该引导程序位于片内Flash,其作用是通过串行口加载HEX格式的程序文件,并自动转换成BIN格式,然后保存到片外RAM,最后跳转过去执行。RAM起始地址为0x8000。引导完毕后,蜂鸣器鸣叫,并等待按下K4键。K4按下后,才开始执行。 【说明:在片外RAM运行的程序】 编写在片外RAM运行的程序与编写正常的A51或C51程序基本相同,但是需要做一些小的调整。正常的程序起始地址总是0x0000,但现在片外RAM的起始地址是0x8000,因此要在原有程序的基础上重新设置起始地址。 对于A51编程,找到ORG命令,修改复位地址和全部断向量入口地址,使它们都偏移0x8000。例如复位地址为0x0000要改成0x8000,定时器T0断入口地址0x000B要改成0x800B,等等。重新编译,生成HEX程序文件,备用。 而对于C51编程,设置的项目稍多一些,步骤如下: 第一,打开Keil C51安装目录“C:\Keil\C51\LIB”,找到文件“STARTUP.A51”,将其复制到您的工程文件夹下,然后右击项目管理窗口的“Source Group1”添加该文件。另一种方法是:在新建工程选择“CPU”后,当出现是否添加启动文件对话框时选择“是”,则文件“STARTUP.A51”会自动被加入。 第二,双击项目管理窗口里的“STARTUP.A51”,找到“CSEG AT 0”这一行,将起始地址“0”改成“0x8000”,保存。 第三,设置片外程序ROM的起始地址和大小。打开编译环境设置(点击工具栏的那个绿色按钮进入该设置),在“Off-chip Code memory”Eprom(在这里,Eprom实际上已被RAM代替)栏第一行填入0x8000和0x3000(共12KB空间)。 第四,程序有可能用到xdata数据,因此还要设置片外数据RAM的起始地址和大小。可以在“Off-chip Xdata memory”Ram栏第一行填入0xB000和0x1000,留足空间(有4KB呀!)。 第五,设置断向量。打开“Options fo Target”设置里的“C51”选项页,找到“Interrupt vectors at...”项,修改为“0x8000”。 OK,所有设置都已完成,重新编译,生成HEX程序文件,备用。 【实验步骤】 1、ISP下载开关扳到“01”,用Flash Magic软件下载程序文件“HexLoader.hex”,暂时不要运行。 2、打开串行调试助手软件ZLGCOMView,操作如下: 勾“HEX发送”(非常重要!); 通信口:选择实际的串行口(通常为COM1); 波特率:4800; 数据位:8; 停止位:1; 点击“打开文件”装入文件夹“在片外RAM运行的程序”下的一个程序文件(HEX格式),在这些程序,所有起始地址都已经预先设置好了; 按实验箱上单片机的RST键,会看到显示“Ready”; 点击“发送文件”,程序开始下载到片外RAM; 下载完毕,出现“OK, press K4...”,蜂鸣器同时鸣叫; 按一次实验箱上的K4键,程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值