您的位置:首页 > 其它

CACHE & TLB (一)

2013-03-08 12:12 232 查看

一.unix内核简单回顾(内存相关)

               1. 当使用传统的分时调度策略的时候,在用户级执行的进程总会被分到时间片内执行,从而让所有的进程公平的共享CPU,在内核态执行的进程却不会分入时间片内执行,只有当前的内核进程明确允许的情况下,才能切换到内核级执行另一个进程。

               2. 线程的开销比进程小主要体现在线程共享进程的地址空间。linux内核中没有线程的概念,使用的线程库,实现的功能是线程调度在内核进行,线程的管理在用户空间进行。从概念上看,每一个进程地址空间都分为用户地址空间和内核地址空间,linux中作进程切换的时候,如果是线程的切换,由于共用用户地址空间,所以用户空间的3G内存映射是不需要切换的,在内核中有对应的mm_struct对应,从而减少切换开销。

               3. 地址空间的分配,一般是3G用户空间,1G内核空间
, 用户空间由text/data/bss/stack这几个部分组成,分别是程序指令,初始化数据,未初始化数据和堆栈。另外一些类型的段,如共享库和共享存储,都包含在用户地址空间内。共享库包括附加的正文,数据和BSS段,它们用于常用的函数和服务。共享存储在后面说明。

               内核空间包括内核的正文和数据结构,当内核正在执行的时候,它可以访问整个地址空间,这样易于让内核在代表用户进程执行一次系统调用的时候可以在用户进程的地址空间中执行。一个内核进程实际上执行的都是内核的正文中的代码,有固定的映射,切换的时候重装task_struct等结构是必须的。

               可以从下图中有个更加清晰的概念:(这里是2G/2G的设计)

                 


               

               4.
地址空间映射

                    线程切换减少开销主要是因为共享用户地址空间,所以用户空间地址映射的物理地址对应关系可以保存下来,不需要切换,从而减少开销。

                    内核负责将一个进程的虚拟地址空间映射到物理地址空间上,由MMU执行。

                   


                   

                        

             每一个进程都有它自己的映射关系,这种映射关系与内存有关,而且作为进程的现场的一部分保存起来。在进程运行的时候,内核将进程映射关系的描述提供给MMU。

           注意,不是所有的虚拟页面都需要映射,例如,上图中的虚拟页面1,5,8就没有被映射到任何物理页面上,它们可以表示进程的地址空间中没有使用的页面,也可以是当前没有驻留在内存中的页面,如果一个进程试图返回后一种类型的页面,发生缺页错误之后,内核会将相应的物理页面调入到内存中,并且把虚拟页面映射到新分配的物理页面上。

           同样,不是存储器中所有的物理页面都由一个进程使用。比如上图的2,4,8,当前正在执行的进程无法访问它们,这些物理页面可以属于系统中的其他进程,或者干脆没有使用。无论何种情况,当前在执行的进程是不允许访问它们的。

           虚拟页面映射到同一个物理页面上,内核就可以让多个进程共享特定的物理页面。

           大多数的MMU会给每一个映射关系关联一个访问权限的能力。比如将内核的正文页面(text
page)映射为只读,同时允许对数据页面的读写访问。(Fork和COW)

           Fork会根据需要进行拷贝物理页面,简单的就是cow(copy-on-write)

          


               


 

         


               

           上面4图能很好的说明fork时的地址映射关系。

                 使用exec时,原来程序的正文、数据、bss和堆栈以及诸如共享存储的其他存        储对象会被抛弃,而为新程序创建新的虚拟地址空间。新程序的正文和初始化数据从           指定文件中读入,而内核将地址空间内的空间分配给bss和堆栈,进程内单个线程的Pc被设定在新程序的起始地址。这个进程的执行实际上看的也是调度,内核中制造   的假象是该进程已经执行很长时间,重新参与调度。新程序可以访问exec调用之前 进程打开的文件,因为这些文件都是和进程相关联的,而不是和程序相关联的。

                 exit或者kill可以终止一个进程,android的zygote退出时不使用exit,而是自己给自己发送一个kill的信号。终止一个进程时,内核必须丢弃进程的地址空间,取消进程正在使用的内核服务,比如关闭进程留下的任何打开的文件。此时进程以一种僵 尸进程的形式存在,使的父进程有机会通过wait读取到子进程的退出状态之前保持进程间的父子关系,最后释放代表进程本身的内部的内核数据结构(如task_struct),一些结构的释放是在父进程中进行的。之后内核执行一次现场切换,选择另外一个要执行的进程。

                系统调用sbrk/brk都是供一个进程用来分配或者回收它的bss段空间。系统调用以BSS段的BReaK
address得名。sbrk/brk能让进程改变它的断开地址,从而增长  或者缩小bss段的大小,增大通过页错误来实现,缩小BSS,那么在新老断开地址之   间地址范围的虚拟地址和物理地址都会被释放,访问权限也变了,进程再也不能访问 它。

               共享存储段位于进程BSS和堆栈段之间未用的虚拟存储区中,便于进程通信,它将一个或者多个物理页面映射到不同进程的不同虚拟地址空间中(不需要是相同的虚拟地址)。

                映射文件,从上面的内存分配和一些记录,能很好的理解映射文件的概念。因为存在物理地址到虚拟地址的映射,unix提供将文件映射到一个进程地址空间内的功能。一旦文件被映射到进程地址空间内,这个文件就可以作为地址空间内一段连续的字节区直接访问,一般映射到用户空间地址。

 

. cache
            1.局部性

                时间局部性和空间局部性

           
2.cache基本原理

                在高速缓存的设计中,要考虑的重要一点是用一个标记确定多少数据。例如,独立地标记告诉缓存中的每一个字节代价太大,因此,来自主存储器的一个或者更多连续的字被组织到一起形成一个高速缓冲行(line)或者块(block),并且给每一行关联一个标记,所以一个完整的高速缓冲行由一个标记和一段数据组成,高速缓冲行的大小是指数据部分的字节数。

                例如,Proc-arm926.S中有如下设置,

/*

 * thecache line size of the I and D cache

 */

#define CACHE_DLINESIZE       32

                 

                 标记部分还包括有效位(validbit),修改位(modified
bit)以及其他依赖实现的信息,    比如key.

                 替换策略有LRU,伪LRU,以及随机替换。

                 写入策略有写直通(write-through)和写回策略(write-back),写直通不存在一致性问题,而写回策略需要注意一致性。Modified
bit就是用于write-back策略的.

                 

           3.cache的组织方式--直接映射高速缓存

            


                     

                  由于许多不同的地址都会被散列到同一行上,一些程序可能导致高速缓存行在被再次命中之前被替换掉,从而导致高速缓存颠簸(cache
thrashing),和进程颠簸类似.

                 

                4.cache的组织方式--双路组相联高速缓存

                   双路组相联高速缓存通过索引一组两行可能保存数据的高速缓冲行,来减少高速缓存的颠簸,但是不能彻底解决此问题.

                  


                              

                  5.cache的组织方式--N路组相联高速缓存     

                       组内的行数并没有理论上的限制,所以有4路或者更多录的组相联高速缓存,到最后就可以将组的大小增加到组内行的数目等于高速缓存内的全部行数,此时只有一组,称作全相联高速缓存.

                  6.cache的组织方式--全相联高速缓存            

                       全相联高速缓存能最大的减小高速缓存颠簸的现象,但是全相联高速缓存构建成本高,因为需要并行搜索高速缓存中的所有行.TLB在这方面比较实用,因为大多数程序都体现出局部引用特性,这意味着工作集的转换会被多次使用,             

                 7.高速缓存冲洗(flush)

                       高速缓存冲洗有两中形式,使主存储器有效(validating
main memory)和使高速缓存无效(invalidating cache).

                       Validating mainmemory指采用write-back
policy的cache将修改过的数据写回到主内存的做法,比如说flush_kern_cache_all函数,这种行为会在每隔一段时间自动完成,也可以由操作系统明确的控制.

                       Invalidating cache指直接将cache数据抛弃的做法,这个对于write-back
policy和write-through policy均适用.

                  8.icache & dcache

                  


                     9.高速缓冲的性能

                                           


                       10.如何区分不同的高速缓存结构

                       高速缓存大小

                       行大小

                       组大小

                       写分配的使用

                       替换策略

                       按照虚拟或者物理地址查找

                       如何标记行(通过虚拟地址、物理地址还是其他信)

                       写直通或者写回策略.

 

 

PS: 下篇会说到虚拟高速缓存和物理高速缓存,再下篇分析源码。

                 

 

 

 

 

           

 

                
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: