⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter4.htm

📁 mips run 中文版
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<BR>如果一个设备从内存中取得数据,它必须取得正确的数据。如果D-cache是write-back,并且程序已经写了一些数据,那么很可能其中一些正确的数据还保留在D-cache中而没有写回到主存中去。CPU当然不可能看到这个问题;如果CPU需要这些数据,它会从cache中得到正确的数据。 
<BR>所以在DMA设备开始从内存中读数据前,任何一个将被读数据如果还保留在D-cache中,必须被写回到内存中。 <BR><BR>. DMA设备写数据到内存: 
<BR>如果一个设备要将数据存贮到内存中,要使cache中任何对应将要写入内存位置的line都无效化,这是非常重要的。否则,CPU读这些位置的数据,将得到错误的数据。cache应该在数据通过DMA写入内存之前将对应的cache 
line无效化。 <BR><BR>. 拷贝指令: 
<BR>当CPU自己为了后面的执行而写一部分指令到内存中,你首先必须保证这些指令会被回写到内存中,其次保证I-cache中对应这些指令的line会被无效化。在MIPS 
CPU中,D-cache和I-cache是没有任何联系的。(当CPU自己写指令到内存中时,这时候指令是被当作数据写的,很可能只被写到cache中,所以我们必须保证这些指令都会被回写到内存中;为什么要使I-cache无效化,这和数据通过DMA直接写入内存中要无效cache一样的原因。) 
<BR><BR><BR>如果你的软件需要解决这些问题,就需要针对cache line的两个独特的操作。 
<BR>第一个操作被称之为回写操作。CPU必须能够针对地址在cache中查找对应的cache 
line。如果找到,并且对应line是dirty,就需要把这条line的数据写回到内存中。 
<BR>CPU增加了其他不同层次的cache(速度和大小),来减少miss的处理。所以设计者可以使内层的cache机构简单,从而使它能在很高的时钟频率上作查询。这样很显然越往内层的cache就会越小。从1998年开始,许多高速的cpu都在同一块芯片上采用第二级cache,主cache的大小变小,双重16K的主cache受到青睐。 
<BR><BR>不在同一块芯片上的cache通常都是直接映射的,因为组相连的cache系统需要更多的总线从而需要更多的管脚来连接。这还是一个值得研究的领域;MIPS 
R10000采用只有一个数据总线的二路组相连cache,如果命中的不是希望的那一组,通过一段延时后在返回数据来实现(两个组共用一个数据总线)。 
<BR>在cache的发展过程中,产生了两类主要的软件接口来针对cache。从软件的观点来看,一类是建立在以R3000为代表的32位MIPS 
CPU的基础上;另一类是建立在以R4000为代表的64位MIPS CPU上的。R3000这一类型的MIPS 
CPU的cache是write-through,直接映射的,物理地址为索引。cache访问的最小单位是一个字,所以写一个字节(或者是写小于一个字)的操作必须被特殊的处理。在读写这一类数据是cache管理采用特殊的模式。 
<BR><BR>为什么不通过硬件来管理cache? 
<BR>通过硬件来管理cache通常被称为“爱管闲事”。当另一个cpu或者是DMA设备访问内存时,被访问地址对应的内容对于cache来说是可以看到的。 
<BR><BR>4.7 第二层和第三层cache 
<BR>在大型的系统中,通常需要一个嵌套的多层cache。一个小而快的主cache最接近cpu。访问主cache出现miss时,不是直接从内存中查找而是从第二层cache中查找。第二层cache在速度和大小上是介于主cache和内存之间。cache层次的数目可以通过内存速度和cpu最快访问速度比较来决定;由于cpu速度发展比内存的发展快得多,在过去的12年里桌上型电脑系统从没有cache发展到有两层cache。九十年代后期的最快cpu速度大约可以达到500MHz,拥有三层cache。 
<BR><BR><BR><BR><BR>4.8 MIPS CPU cache的构造 
<BR>通过观察cache采用模式和层次的发展(看表4.1),我们可以将MIPS CPU分成两类,古老的和现代的。 
<BR>当时钟的速度变得越快,我们就能看到越多得cache构造,因为设计者为了应付CPU跑得速度比内存系统越来越快。为了保证运行的顺畅,cache必须提高运行速度,保证提供数据的速度比外围得存贮器要快,同时也要保证尽可能多命中。相比较R4000类型的CPU,主cache是write 
back类型,是write allocate ,virtually indexed,physically tagged, 二路或四路组相连的cache。 
<BR>许多R4x00和其后续cpu在同一块上拥有第二层cache的控制器,1998年出现了这样的第一块cpu。 
<BR>由于两种产生的不同,我们将分两节来详细介绍。 <BR><BR>注意!一些系统的第二层cache不是由mips 
cpu内部的硬件来控制的,而是建立在内存的总线上。对于这类cache的软件接口将具有系统特殊性,和象这章介绍的由cpu内部控制的cache的软件接口相比,可能有很大的不同。 
<BR><BR>4.9 Programming R3000-Style Caches <BR>MIPS 
R2000打破了芯片内cache控制器的基础,将cache额外的分成I-cache和D-cache。这是一个后见之明,不会让人感到惊讶,就是这样一个先驱者的冒险导致了后面很多事端。cache有一个特殊的软件访问缺点。 
<BR>为了节省芯片管脚,cache将不能拥有不同的闸门来执行字节、半个字和其他小于一个字单位的写操作。所以在R2000系列中对cache执行一个小于字单位的写操作时,会回写到主存中,并将cache中这个字所在的Line无效化。这样针对cache管理,提供了一个使cache无效的方法:只用写一个字节就行了。 
<BR>你可以看到支持这些简化的观点。R2000设计者提出理由小于字的操作通常用于字符操作,字符操作总是由库函数提供,而这些库函数用整个字的操作来重写。这些假设总是被认为对对错错,或者半对半错。 
<BR>直到认识到不是所有系统都能用相同的函数库,而且每个字节写操作都使所在cache无效也不是一个好主意,这些争论才没有继续下去。因为这是不能被容忍的,所以出现了一个很大的改动,R3000系列的cpu通过一个RMW(read-modify-write)序列来执行小于字单位的写操作。这个RMW出现在所以的32位的mips 
cpu中,并增加了一个 时钟周期来作为这样一个写操作的延时。 
<BR>这样cache无效的机制被带入困境;R2000因为它的奇怪习惯而有一个优点,可以通过字节的写操作来使cache无效化。而R3000 cache 
需要用一个叫isolation的模式来挽救,原来这种模式只是用于cache诊断的。RMW队列因为这种模式而受到压制,在那种状态下小于一个字单位的写操作还是会让该字所处的line无效化。这是不幸的但不是悲惨(灾难)的,对于一些运行着的系统做一些事有着更有益的地方。显著的就是当cache在isolation模式时的时候,cache将没有读写操作,任何读写操作将直接和内存打交道。 
<BR><BR>4.9.1 Using Cache Isolation and Swapping 
<BR>所有的R3000系列cpu的cache都是write-through模式的,这就是说cache中不会拥有比内存中更新的数据。也就是说cache中的数据从来都不需要回写到内存,所以我们只需要能使D-cache和I-cache无效就行了。 
<BR>只需要不同的cache操作按照内存顺序来做cahce的管理,并且cache的管理没有必要通过特殊的内存地址空间。所以这儿有一个状态寄存器有一个SR位能够使D-cache关闭isolation模式;在这种模式下读写操作只影响着cache,读还是会命中但不管tag是不是相等。当D-cache处于isolation模式时,小于一个字单位的写操作会使对应cache 
Line被无效化。 <BR><BR>CAUTION!!! 
<BR>当D-cache处于isolation模式,任何读写操做不会受其对应地址或TLB条目的影响而按照非cache的情况操作。这样的结果就是cache管理程序必须保证有些数据是不可以被访问的;如果你能通过你的编译器做到很好的控制,并且能过保证所有你用的变量都保存在寄存器中,你才能在很高级别的语言中写它们。还必须保证运行这些程序时屏蔽中断。 
<BR><BR>I-cache在通常运行模式下也是完全不可访问的。所以CPU提供了另一种模式,cache交换(swapped),通过设置状态寄存器的SwC位;这时D-cache可以担当I-cache,I-cache可以担当D-cache。当cache是交换模式时,isolated的I-cache条目可以被读、写和无效化。 
<BR>D-cache可以完美的充当I-cache使用(可能I-cache也可以通过初始化使之象D-cache一样工作),但I-cache不能完全的充当D-cache。这也是靠不住的,当cache是交换模式时有用,isolation却没有用。 
<BR>如果你需要使用交换的I-cache来存储字单位的数据(和以前一样小于字单位的数据写操作会使该数据对应的line被无效化),你必须保证在返回到正常模式时对应的cache 
line必须被无效化。 <BR><BR>4.9.2 Initializing and Sizing 初始化和判断大小 
<BR>当机器启动时cache的状态是不确定的,所以这时读cache结果也是不可预知的。你也应该认识到机器重起后状态寄存器的SwC位和IsC位也是不确定的,所以在对cache读写前(即使在非cache的情况)启动软件最好能将这些状态设为可知的。 
<BR>不同的MIPS 
CPU,cache有不同的大小。为了保证你软件的可移植性,最好能在初始化的时候计算出D-cache和I-cache的大小。这样比直接配置一个给定的值好。 
<BR>下面将介绍怎样获得cache大小的值: <BR>a. Isolated cache,让I-cache处于交换模式。 <BR>b. 
在R3000系列CPU中,cache的大小可能是256K,128K,64K,32K,16K,8K,4K 
,2K,1K和0.5K(K等于1024,单位是字节)。将这些可能的值n(上面那些值中的一个)写到物理地址等于它们本身的地方(有大到小)。最简单产生物理地址是用Kseg0段地址(n+0x80000000)。因为cache地址是重叠循环的,那么如果n是cache大小的倍数,那么它就会被后面小的值所覆盖。 
<BR>c. 所以读物理地址零(也就是0x80000000),就能得到cache大小的值。 
<BR><BR>初始化cache,你必须保证每一个cache条目都被无效化,而且正确对应一个内存位置,所含的之值也是正确的: <BR>a. 
检查状态寄存器SR的PZ位是不是位零(为1的话,关闭奇偶位,对于同一个芯片上的 cache这不是一个好主意)。 <BR>b. isolated 
D-cache,并使它和I-cache交换。 <BR>c. 
对于cache的每一个字,先写一个字的值(使cache的每条line的tag、数据、和奇偶位都正确),然后再写一个字节(使每条line都无效)。 
<BR>不过要注意当对于每条line有四个字的I-cache,这样做效率就很低;因为只要写一个字节就足够使每条line无效了。当然除非你要经常调用这个使cache无效程序,否则这个问题是不会表现的很明显。不过如果你想根据实际情况来优化cache无效化程序,就需要在启动的时候确定cache的结构。 
<BR><BR><BR>4.9.3 cache无效化(Invalidation) <BR>使cache无效,按照下面的流程: <BR>a. 
计算出你使cache失效所需的地址范围。使用超过cache大小的范围是浪费时间。 <BR>b. 
使D-cache孤立。一旦被孤立后你就不能读写内存,所以你必须花费所有的代价来防止异常的产生。关闭所有的中断并保证后面的程序都不会导致内存访问异常。 
<BR>c. 如果你还想使I-cache失效,使cache处于交换模式。 <BR>d. 在刚才计算出的地址范围内针对每一条line写一个字节的内容。 
<BR>e. 关闭cache的交换和孤立模式。 
<BR>通常你应该在I-cache打开的模式下运行使cache失效的程序。这听起来是混乱和危险的,但事实上你没有必要花费额外的步骤去跑cache。一个使cache失效的程序在cache关闭的情况下运行要慢4到10倍。 
<BR>当你的CPU去设IsC位时,本质上必须关闭所有的中断,因为这时是不能访问内存的。 <BR><BR>4.9.4 测试和探察 
<BR>在测试、调试或profiling时,画一个cache条目的示意图是很有帮助的。 你不能直接的读tag的值,但对于合法的line有详尽的方法得到: 
<BR>a. Isolate the cache. <BR>b. 
通过每条line的起始地址从每条line里取得(低位地址匹配,高位地址包括你系统的内存的物理地址范围)。每一次读取都要参考状态寄存器的CM位,只有该位为零时,取得的tag值才是正确的。 
<BR><BR>这需要很多个计算机的周期,不过对于在20MHz的处理器,1K的D-cache对应4MB的物理内存,做整个查询就只需要几秒钟。 
<BR><BR>4.10 Programming R4000-Style Caches <BR>R4000修改了早期cpu 
cache不合适的地方。但R4000成功的地方就在于cache有多种工作模式(write-back , 
write-allocate),以及拥有更长的line。因为有write-back工作模式,当被cpu写时每一条line都需要一个状态位来标志这条line为dirty(因此来表示很内存中的数据不同)。 
<BR>对于这类cache,我们需要invalidate和write-back操作:而且还必须保证任何cpu写到cache中的数据必须被回写到内存中。 
<BR>对于诊断和维护的目的,tag将更容易的被读写;R4000增加了一对寄存器TagLo和TagHi用来在cache 
tag和系统管理软件之间中转数据。对于R4000没有直接方式读取cache line内的数据,当然你还是可以通过cache 
命中的方式来访问数据。CPU可以通过执行cache指令来从cache 
tag内取数据到32-bit的TagLo和TagHi寄存器中,或者是将这些寄存器的内容写到cache tag。图4.3显示这些寄存器的详细内容。 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -