电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

cache 学习

           最近工作不是很忙了,跑的TC都需要时间比较长了,所以终于有时间可以学习一下自己的感兴趣的东西,自己想想,整天自己算作SOC组的,那soc主要的是什么啊,说白了还是在玩IP,呵呵,那最关键的是什么呢,不用说当然是arm,大家当然得听脑袋发话干事了,但是发现自己一直用的就是一个arm的模型而已,自己对它的了解还真是少的可怜,得,慢慢学吧,先学习最近用得比较多的cache吧。

ARM920T的MMU与Cache

Cache是高性能CPU解决总线访问速度瓶颈的方法,然而它的使用却是需要权衡的,因为缓存本身的动作,如块拷贝和替换等,也是很消耗CPU时间的。MMU的重要性勿庸置疑,ARM920T(和ARM720T)集成了MMU是其最大的卖点;有了MMU,高级的操作系统(虚拟地址空间,平面地址,进程保护等)才得以实现。二者都挺复杂,并且在920T中又高度耦合,相互配合操作,所以需要结合起来研究。同时,二者的操作对象都是内存,内存的使用是使用MMU/Cache的关键。另外,MMU和Cache的控制寄存器不占用地址空间,CP15是操纵MMU/Cache的唯一途径。             Cache/Write Buffer的功能

Cache通过预测CPU即将要访问的内存地址(一般都是顺序的),预先读取大块内存供CPU访问,来减少后续的内存总线上的读写操作,以提高速度。然而,如果程序中长跳转的次数很多,Cache的命中率就会显著降低,随之而来,大量的替换操作发生,于是,过多的内存操作反而降低了程序的性能。

ARM920T内部采用哈佛结构,将内部指令总线和数据总线分开,分别连接到ICache和DCache,再通过AMBA总线接口连接到ASB总线上去访问内存。Cache由Line组成,Line是Cache进行块读取和替换的单位。

Writer Buffer是和DCache相逆过程的一块硬件,目的也是通过减少memory bus的访问来提高性能。

MMU的功能

在内存中维护一张或几张表,就看你怎么给内存划分page和section了。通过CP15指定好转换表的位置,920T的硬件会自动将转换表的一部分读到TLB中。CPU每次进行内存读写时,发出虚拟地址,参照TLB中的转换表转换到物理地址,并读取相应entry中的信息,以决定是否可以有权限读写和缓存。

mmugen这个工具就是帮你构造这个表的,省的自己写程序了。

操作MMU,实际上就是如何分配和使用你的内存,并记录在translationtable里。

ARM920T中,MMU的每条entry包括Cachable和Buffable位来指定相应的内存是否可以用Cache缓存。此处就是MMU与Cache的交互作用处。

实际上,MMU和Cache的使用是操作系统设计者根据系统软硬件配置而考虑的事情。操作系统针对分配给应用程序的地址空间作内存保护和缓存优化。在没有操作系统的情况下,就需要我们自己来掌控它们了。其中,主要是合理分配内存。

我认为,以下几点需要着重考虑:

1) 安全第一! -- 避免MMU和Cache的副作用。

当你在无OS的裸机上开发程序时,初始化运行环境的代码很重要,比如:各种模式堆栈指针的初始化;将代码和RW data从ROM拷贝到RAM;初始化.bss段(zero initialized)空间等。此时会有大量的内存操作,如果你enable了Cache,那么在拷贝完代码之后,一定要invalidate ICache和flush DCache。否则将会出现缓存中的代码或数据与内存中的不一致,程序跑飞。

另外,有时候我们需要自己作loader来直接运行ELF文件,情况也是一样,拷贝完代码后一定要刷新Cache,以免不测。

还有,对硬件的操作要小心。很多寄存器值都是被硬件改变的,读写时,要保证确实访问到它的地址。首先,在C语言代码中声明为volatile变量,以防止内存读写被编译器优化掉;另外,设置好TLB,使得寄存器映射的地址空间不被缓存。

总之,缓存和内存中代码的不一致,是一定要避免的。

2) 弄巧成拙! -- 只对频繁访问的地址空间进行Cache优化。

我们很清楚自己的程序中,那里有大量的运算,哪里有无数的循环或递归,而这正是Cache的用武之地,我们将这些空间进行缓存将大大提高运行速度。但是,很多函数或子程序往往仅仅运行很少几次,若是对它们也缓存,只会捡了芝麻丢了西瓜,造成不必要的缓存和替换操作,反而增加了系统负担,降低了整体性能。

3) 断点哪儿去了? -- 如何调试“加速”了的代码?

据我所知,一般,debugger都是通过扫描地址总线,在断点处暂停CPU。ARM9TDMI中集成的JTAG调试口,也是这样。

当我们调试使用Cache的代码时,将会出现问题。比如:CPU访问某断点所在地址之前的地址时,发生缓存操作,断点处代码被提前读入Cache,此时地址总线上出现了断点地址,CPU被debugger暂停,并且断点之后的指令也被Cache缓存。于是,当你从断点处step时,程序却停不了了,因为地址总线上不再出现断点之后的下一个地址了。

   再举个例子:

       int i,a;

       for (i=0; i<100; i++) {

    ->     a++;    /* set breakpoints */

       }

 

当地址总线上第一次出现断点地址时,CPU暂停;之后,就再也不会停了。因为,之后CPU会从cache中直接去代码了。(当然,后来,Cache的代码有可能会被替换掉,断点又可到达。)  所幸的是,我用的debugger提供JTAG Monitor,允许断点跟踪使用cache的程序。

Cache的工作原理
    1.Cache的引入
    请注意下面两种情况:
    ①大容量主存一般采用DRAM,相对SRAM速度慢,而SRAM速度快,但价格高。
    ②程序和数据具有局限性,即在一个较短的时间内,程序或数据往往集中在很小的存储器地址范围内。    
    因此,在主存和CPU之间可设置一个速度很快而容量相对较小的存储器,如图3.35所示。在其中存放CPU当前正在使用以及一个较短的时间内将要使用的程序和数据,这样,可大大加快CPU访问存储器的速度,提高机器的运行效率。

 
    通过上面的例子,可以这样来描述(2ache最基本的工作原理:在存储系统中设置了Cache的情况下,CPU进行存储器访问时,首先访问Cache标记,判是否命中,如果命中,就访问Cache(数据部分),否则访问主存。
    将访问的数据在Cache中的次数(即命中的次数)与总的访问次数之比称为命中率。影响命中率的因素主要有三个:Cache的容量、Cache块的划分以及Cache块与主存块之间的映像关系。一般来说,Cache的容量大一些,会提高命中率,但达到一定程度时,命中率的提高并不明显。目前,一般为256 KB或512 KB,命中率可达98%左右。
    下面还是通过例子来说明引入Cache块的好处。已知Cache的存取周期为50 ns,主存的存取周期为250 ns。设命中率为98%,即100次访问存储器的操作有98次在Cache中,只有2次需要访问主存,则这100次访问存储器操作的平均存取周期为(50 ns×98+250 ns×2)÷100=54 ns。由此可见,由于引入了Cache,使得CPU访问存储器的平均存取周期由不采用Cache时的250 ns降到了54 ns。也就是说,以较小的硬件代价使Cache/主存储器系统的平均访问时间大大缩短,从而大大提高了整个微机系统的性能。   
需要指出,Cache的功能全部由硬件实现,涉及Cache的所有操作对程序员都是透明的。
3.Cache的读/写操作
    CPU进行存储器读操作时,根据主存地址可分成命中和未命中两种情况。对于前者,从Cache中可直接读到所需的数据;对于后者,需访问主存,并将访问单元所在的整个块从内存中全部调入Cache,接着要修改Cache标记。若Cache已满,需按一定的替换算法,替换掉一个旧块。   
  CPU进行存储器写操作时,也可分成两种情况。一是所要写入的存储单元根本不在Cache中,这时写操作直接对主存进行操作(与Cache无关);二是所要写入的存储单元在Cache中。对于第二种情况需做一些讨论。Cache中的块是主存相应块的副本,程序执行过程中如果遇到对某块的单元进行写操作时,显然应保证相应的Cache块与主存块的一致。
这里有两种处理方式。一是暂时只向Cache写入,并用标志注明,直到这个块被从Cache,中替换出来时,才一次写入主存,称之为回写式;二是每次写入Cache的同时也写入主存,称之为通写式。两种方式各有优缺点。回写式占用总线时间少,写速度快,但不能随时保证Cache与主存保持一致,如果此期间发生DMA操作,则可能出错(DMA操作将在第四章介绍,暂时可将其理解为在输入/输出设备与存储器之间直接进行数据传送,这种操作不需要CPU参与。所以,可能出现CPU和DMA控制器同时访问同一主存块的情况);通写式可使Cache块和主存块始终保持一致,但占用总线时间长,总线冲突较多。

转自:

Cache的原理、设计及实现

Cache的原理、设计及实现 cM{04#z   b/0\DD0<   )%I ;7=<   前言 RG +0pqB*   EHQ_Xq     虽然CPU主频的提升会带动系统性能的改善,但系统性能的提高不仅仅取决于CPU,还与系统架构、指令结构、信息在各个部件之间的传送速度及存储部件的存取速度等因素有关,特别是与CPU/内存之间的存取速度有关。 1C-J   ,C.daL8     若CPU工作速度较高,但内存存取速度相对较低,则造成CPU等待,降低处理速度,浪费CPU的能力。 ,0"3G^;nv{   @rG!@s;     如500MHz的PⅢ,一次指令执行时间为2ns,与其相配的内存(SDRAM)存取时间为10ns,比前者慢5倍,CPU和PC的性能怎么发挥出来? 2>/.qopY   }, vCDW,@     如何减少CPU与内存之间的速度差异?有4种办法: ?aHk>a]}!   qzB^3[8}  
  一种是在基本总线周期中插入等待,但这样会浪费CPU的能力。 |GxlE}IF  
>#-NI  
  另一种方法是采用存取时间较快的SRAM作存储器,这样虽然解决了CPU与存储器间速度不匹配的问题,但却大幅提升了系统成本。 oeuw,}S  
\|=&@$A!x\  
  第3种方法是在慢速的DRAM和快速CPU之间插入一速度较快、容量较小的SRAM,起到缓冲作用;使CPU既可以以较快速度存取SRAM中的数据,又不使系统成本上升过高,这就是Cache法。 rcL~?  
)cQX  
  还有一种方法,采用新型存储器。 z9q0DdR7  
%5s%]-     目前,一般采用第3种方法。它是PC系统在不大增加成本的前提下,使性能提升的一个非常有效的技术。 ]f3Yd@j   E*tj^ h     本文简介了Cache的概念、原理、结构设计以及在PC及CPU中的实现。 JNN!d   h L!?27pH   v<3i*5"     Cache的工作原理 qV zb   {>R#=t     Cache的工作原理是基于程序访问的局部性。 )xvyf8tU   hnBY) x     对大量典型程序运行情况的分析结果表明,在一个较短的时间间隔内,由程序产生的地址往往集中在存储器逻辑地址空间的很小范围内。指令地址的分布本来就是连续的,再加上循环程序段和子程序段要重复执行多次。因此,对这些地址的访问就自然地具有时间上集中分布的倾向。 qu+1)/p7X   H\i>H9O  
  数据分布的这种集中倾向不如指令明显,但对数组的存储和访问以及工作单元的选择都可以使存储器地址相对集中。这种对局部范围的存储器地址频繁访问,而对此范围以外的地址则访问甚少的现象,就称为程序访问的局部性。 JEx)ivHO,  
Zeu=.1
,  
  根据程序的局部性原理,可以在主存和CPU通用寄存器之间设置一个高速的容量相对较小的存储器,把正在执行的指令地址附近的一部分指令或数据从主存调入这个存储器,供CPU在一段时间内使用。这对提高程序的运行速度有很大的作用。这个介于主存和CPU之间的高速小容量存储器称作高速缓冲存储器(Cache)。 ]{ T N 3W  
ye{~}+  
  系统正是依据此原理,不断地将与当前指令集相关联的一个不太大的后继指令集从内存读到Cache,然后再与CPU高速传送,从而达到速度匹配。 '/5n2v6$T  
6D2 80E 
  CPU对存储器进行数据请求时,通常先访问Cache。由于局部性原理不能保证所请求的数据百分之百地在Cache中,这里便存在一个命中率。即CPU在任一时刻从Cache中可靠获取数据的几率。
S  u}cd+v }     显然,将来随着半导体集成工艺的提高,如果CPU与二级Cache集成在单芯片上,则CPU与二级Cache的耦合效果可能更佳。 cCD&2\*A  
Ee{N  
  由于L2 Cache内置,因此,还可以在原主板上再外置大容量缓存1MB~2MB,它被称为L3 Cache。 ?Rv/CIT2  
0x)DFrrB8  
7$vM{(%Y2_  
!s$x'^!i  
PC中的Cache技术的实现 hGqn%'~x1  
@9C83j1  
  PC中Cache的发展是以80386为界的。 qQ"|;  
M5/%ynO  
结语 &2QAeI  
MH9]/9  
  目前,PC系统的发展趋势之一是CPU主频越做越高,系统架构越做越先进,而主存DRAM的结构和存取时间改进较慢。因此,Cache技术愈显重要,在PC系统中Cache越做越大。广大用户已把Cache做为评价和选购PC系统的一个重要指标。本文小结了Cache的源脉。希望可以给广大用户一个较系统的参考。 yjmsv8  

博主
jerryer@126.com
润物细无声
点击跳转