自己学驱动15——Cache

1.Cache简介

同样是基于程序访问的局部性,在主存和CPU通用寄存器之间设置一个高速的、容量相对较小的存储器,把正在执行的指令地址附近的一部分指令或数据从主存调入这个存储器,供CPU在一段时间内使用,这对提高系统的性能很有帮助。这个位于主存和CPU之间的高速小容量存储器称作高速缓冲器(Cache)。

启用Cache之后,CPU读取数据时,如果Cache中有这个数据的副本则直接返回,否则从主存中读入数据,并存入Cache中,下次读取这个数据时,可以直接使用Cache中的副本。

2.Write Through模式与Write Back模式

启用Cache之后,CPU写数据时有Write Through和Write Back两种方式。

(1)Write Through模式

任一从CPU发出的写信号送到Cache的同时,也写入主存,以保证主存的数据能够同步的更新。这种方法的特点是操作简单,但由于主存速度相对较低,所以降低了系统的写速度并且占用了较多的总线时间。

(2)Write Back模式

数据一般只写到Cache,这样有可能出现Cache中数据得到更新而主存中的数据不变的情况,当Cache中的数据被换出或者强制进行"清空"操作时,才将更新的数据写入主存相应的单元中。

3.Cache的两个操作

(1)"清空":把Cache或Write buffer中已经更新过的数据写入主存。

(2)"使无效":是之不能再使用,并不将更新过的数据写入主存。

4.2440内置的指令Cache、数据Cache和写缓存(Write buffer)

(1)指令Cache(ICaches)

ICaches的使用比较简单,系统刚上电或复位时,ICaches中的内容是无效的,并且ICaches功能是关闭的。往Icr(CP15协处理器寄存器1中的第12位)写1可以启动ICaches,写0可以停止使用ICaches。

ICaches一般在MMU开启之后被使用,此时页表描述符中的C位(Ctt)用来表示一段内存是否可以被Cache。但是即使MMU没有开启,ICaches也是可以被使用的,这时CPU读取指令时所涉及的内存都被当做是允许Cache的。ICaches被关闭时,CPU每次读取指令都要读取主存,性能非常低,所以应尽早启动ICaches。

ICaches被开启后,CPU每次读取指令时都会先在ICaches中查看是否能够找到所需要的指令,而不管Ctt是0或1。ICaches开启后,CPU的读取指令分为如下3种情况:

A.Cache命中且Ctt为1(Ctt=1表示允许被Cache),从ICaches中读取指令,返回CPU。

B.Cache缺失且Ctt为1,CPU从主存中读取指令。同时会将指令所在区域的8个word写入某个ICaches条目中,替换算法使用Pseudo-random或round-robin算法,具体可以用CP15中的寄存器1的1位来确定使用哪种替换算法。

C.Ctt为0时,CPU从主存读取指令。

(2)数据Cache(DCaches)

系统上电或复位时默认DCaches是关闭的,Write buffer中的内容也是无效的。往Ccr位(CP15协处理器寄存器1的12位)写1可以启动DCaches,写0关闭DCaches。Write buffer与DCaches紧密结合,没有专门的控制位来开启或停止它。

DCaches必须在MMU开启会后才能使用,因为开启MMU之后才能使用页表中的描述符来定义一块内存如何使用DCaches和Write buffer。

DCaches被关闭后,CPU每次读写数据都要操作主存,DCaches和Write buffer被完全忽略。DCaches开启后,CPU每次读写数据都会先在DCaches中查看是否能找到所需要的数据,而不管Ctt是0还是1。

5.Cache和主存的映射

Cache和主存之间的映射方法大致为三种:全相联映射、直接相联映射和组相联映射。Cache和主存都被划分为同样大小的块,以下假设主存被划分为300(1~300)块,Cache被划分为10(1~10)块做说明。

(1)全相联映射

主存中1~300中的任一块的块可以映射到Cache1~10中的任一块,这种方法的特点是简单,但是查找效率低。

(2)直接相联映射

假设主存中1~30块只能映射到Cache的1号块中,依次类推。这样相比全相联查找效率高,根据VA很快可以获取查找结果(命中或缺失)。

(3)组相联映射

直接相联映射在处理抖动时会出现频繁的置换Cache,即主存中1、2、3号内存被交替访问时,将会出现不停的置换Cache中的1号块。组相联结合全相联和直接相联的特点,将Cache分为大块(大块使用直接相联),小块使用全相联,可以有效的避免抖动访问带来的影响。

6.2440的MMU、TLB及Cache控制指令

2440的协处理器也是一个微处理器,用来帮助主CPU完成一些特殊功能,比如浮点计算等。对于MMU、TLB和Cache的操作就涉及到协处理器。CPU核和协处理器之间传送数据时使用这两条指令:MRC和MCR,它们的格式如下:

<MCR|MRC> {cond} p#,<expression1>,Rd,cn,cm{,<expression2>}

MCR:从协处理器获得数据传递给CPU核

MRC:从CPU核获取数据传递给协处理器

{cond}:执行条件,省略时表示无条件执行

p#:协处理器序号

<expression1>:常数1

Rd:CPU核寄存器

cn和cm:协处理器中的寄存器

<expression2>:常数2

7.Cache操作注意点

与TLB类似,使用Cache时需要保证Cache、Write buffer的内容和主存的内容保持一致,需要遵循以下两个原则:

(1)清空DCaches,使得主存数据得到更新。

(2)清空ICaches,使得CPU读取指令时重新读取主存。

在实际编写程序时,要注意以下几点:

(1)开启MMU前,使无效ICaches、DCaches和Write buffer。

(2)关闭MMU前,清空ICaches、DCaches,即将更新过的数据写入主存。

(3)如果代码右边,使无效ICaches,这样CPU取指令时会重新读取主存。

(4)使用DMA操作可以被Cache的内存时:将内存的数据发送出去时,要清空Cache;将内存的数据读入时,要使无效Cache。

(5)改变页表中地址映射关系时也要慎重考虑。

(6)开启ICahces或者DCaches时,要考虑ICahces或者DCaches中的内容与主存是否一致。

(7)对于I/O地址空间,不使用Cache和Write buffer。所谓I/O地址空间,就是对于其中的连续两次的写操作不能合并在一起,每次读/写都必须是直接访问设备,否则程序的运行结果无法预料。

时间: 2024-10-29 08:22:35

自己学驱动15——Cache的相关文章

写一个块设备驱动15完

http://blogold.chinaunix.net/u3/108239/showart.php?id=2144637 第15章(最终章) +---------------------------------------------------+|                 写一个块设备驱动                  |+---------------------------------------------------+| 作者:赵磊                    

1108: 零起点学算法15——交换变量

1108: 零起点学算法15--交换变量 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 3266  Accepted: 1706[Submit][Status][Web Board] Description 水题 Input 输入2个整数(题目包含多组测试数据) Output 输出交换后的2个整数(每组测试数据一行,中间用空格隔开) Sample Input 825 23 Sample Outpu

自己学驱动13——内存管理单元MMU(虚拟地址和物理地址)

1.MMU简介 MMU负责完成虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查.现代的多用户多进程操作系统通过MMU使得各个用户进程都拥有自己独立的地址空间:地址映射功能使得各个进程拥有"看起来"一样的地址空间,而内存访问权限的检查可以保护每个进程所使用的内存不会被其他进程所破坏.MMU增加了底层的复杂性,但是为上层程序开发提供了极大的方便. 2.虚拟地址与物理地址 虚拟地址最终需要转换为物理地址才能读写实际的数据,这通过将虚拟地址空间.物理地址空间划分为同样大小的一块块空间

LCD驱动 15 -2

1.分配一个fb_info结构体: framebuffer_alloc 2.设置 3.注册 4.硬件相关操 struct fb_fix_screeninfo { char id[16];   /* identification string eg "TT Builtin" */ unsigned long smem_start; /* Start of frame buffer mem */     /* (physical address) */ __u32 smem_len;   

零基础学python-2.15 回到我们的游戏 加入for以及列表

我们先贴上之前的代码,回顾一下功能 import random secret=random.randint(1,100)#生成随机数 #print (secret) time=6#猜数字的次数 guess=0#输入的数字 minNum=0#最小随机数 maxNum=100#最大随机数 print("---------欢迎来到猜数字的地方,请开始---------") while guess!=secret and time>=0:#条件 guess=int(input("

自己学驱动8——uboot代码阅读三(start.S)

/* Set up the stack                            */ stack_setup: ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot   */ sub    r0, r0, #CFG_MALLOC_LEN    /* malloc area                      */ sub    r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo   

自己学驱动9——uboot代码阅读四(start_armboot函数)

前面分析过在start.S中执行完相关的一些操作之后,会跳转到C语言的部分来执行,跳转到的目标位置就是start_armboot函数,所以现在来看一下这个函数完成了一些什么工作.在这个函数的第一行定义了一个变量如下: init_fnc_t **init_fnc_ptr; 通过查找uboot源码可以得到下面的类型重定义: typedef int (init_fnc_t) (void); typedef的使用方法非常灵活,这里这种定义方式就是定义了init_fnc_t代表一个接收参数为void类型返

[小明学Shader]15.基于Grid的地形混合shader

1.写在前面 好久没有写博客了,最近面试不太顺利,认识到应该把学习心得或者说是结果都落实到博客上来,一来加深印象,二来有利于自我展示. 本片博客的内容是讲地形纹理混合,是关于手游sgl大地图的shader实现. slg大地图,如cok,是很大的.在渲染时,只渲染屏幕周围的一部分. 在渲染屏幕地形时,会提供一组地形数据,shader会根据地形数据对地形进行混合. 2.混合方法 混合使用的方法是非常常见的纹理混合. 基本原理是为shader提供多张可以选用的地形贴图.然后根据一张alpha贴图或者其

自己学驱动10——arm-linux-选项

1.arm-linux-gcc选项 总体选项 (1)-E:预处理之后立即停止,不进行编译. (2)-S:编译后停止,不进行汇编. (3)-c:预处理.编译和汇编源文件,但是不作链接,编译器根据源文件生成obj文件. (4)-o:指定输出文件名.这个选项可以使用在预处理.编译.汇编以及连接中,需要注意的是obj文件后缀为.o,而汇编文件的后缀为.s. (5)-v:显示制作GCC工具自身时的配置命令:同时显示编译器驱动程序.预处理器.编译器的版本号. 预处理:处理宏定义以及#include语句. 编