分类: LINUX
2012-05-30 11:25:47
虚拟地址VA到物理地址PA以页page为单位。通常page的大小为4K。物理页面成为page frame。
查看应用程序进程的地址空间,可以看到分为很多段,比如代码段(只读)、数据段(读写)、堆、共享库(其中进一步分段)、栈空间等。整个应用程序的地址空间不会用满4GB,因为还有一部分是内核空间,应用程序不能访问。
再打开一个相同的应用程序查看其进程的地址空间,也是类似的,甚至是一样的。因为采用采用了虚拟地址,经过转换在物理地址上还是分开的。(代码段可能没有分开,因为可以共用)
采用虚拟内存的原因:
1.让每个进程有独立的地址空间,一个好处是某个进程不会破坏其他进程,另一个好处是每个进程都认为有4GB地址空间,编程方便。
2.物理上分开地址空间,经过虚拟内存的管理,可以使得逻辑上是连续的。
3.
所有进程的虚拟内存之和可能大于物理内存。这是通过借用磁盘来实现的,将一时不用的虚拟内存保持到磁盘。磁盘上这部分成为交换设备,可以是分区,也可以是
一个文件。所以系统中可分配的内存总量 = 物理内存的大小 + 交换设备的大小 。交换的过程成为页的换入和换出,期间需要对内存重新映射。
4.增加内存的保护属性,如内核地址空间、只读地址空间等。
虚
拟地址到物理地址是一个查表的过程,但可能不只一个表,是一个多级的表。虚拟地址本身分为几个部分,page地址和page内地址(对于4KB的页来说就
是11bit),page地址分为多级用于查表。这个过程称为Translation Table
Walk,由硬件完成。上述所指的表,是保存在内存上的。
page大,page table小;
page大,减少TLB的miss;
page大,分配memory容易造成浪费;
上
图给出了CPU,MMU,Cache的布局,MMU应该包括了TLB和Translation Table Walk。TLB(Translation
Lookaside Buffer)是一块高速缓存,缓存最近查找过的VA对应的页表项。如果TLB中有需要查表的VA,就不用Translation
Table Walk了,Translation Table Walk较慢要从内存上读表。
Cache
的储存单位是line,假设每个line有32bytes。为了表示某个line是属于哪个VA的,Cache里还有TAG。最简单的TAG就是VA的地
址了(按32bytes的line对齐),Cache控制器检查CPU给出VA和TAG是否一致,一致的话表示命中(Hit),将数据返回给CPU,否则
的话靠MMU转成PA从内存中读取数据。
上述这个Cache的设计称为全相联,特点是一个VA可以缓存到任何line里,但问题是Cache可能有很多line,比如512个line,每次都需要一个个TAG比较过来,这样速度较慢。
另一种Cache的设计称为直接映射,特定的VA只能存在特定的Cache line里,映射规则为Cache line = (VA line)%(Cacle line总数)。这样的问题是Cache line里的数据进出可能太过于平凡,导致命中率较低。
全
相联Cache和直接映射Cache各有优缺点,全相联Cache查找很慢,但没有抖动问题(命中率低),直接映射Cache则正相反。实际CPU的
Cache设计是取两者的折衷,把所有Cache Line分成若干个组,每一组有n条Cache Line,称为n路组相联Cache(n-way
Set Associative Cache)。n路组相联Cache的特点是特定的内存行只能放在特定的组内,但是可以放在组内的任意cache
line上。
Cache写回内存有两种模式:
Write
Back:Cache Line中的数据被CPU核修改时并不立刻写回内存,Cache Line和内存中的数据会暂时不一致,在Cache
Line中有一个Dirty位标记这一情况。当一条Cache
Line要被其它VA的数据替换时,如果不是Dirty的就直接替换掉,如果是Dirty的就先写回内存再替换。
Write
Through:每当CPU核修改Cache Line中的数据时就立刻写回内存,Cache
Line和内存中的数据总是一致的。如果有多个CPU或设备同时访问内存,例如采用双口RAM,那么Cache中的数据和内存保持一致就非常重要了,这时
相关的内存页面通常配置为Write Through模式。
page是os的概念,而cache是cpu的概念。虚拟地址和物理地址以page为单位进行操作的,由两部分组成:page地址和page内地址:
采用多路组联的cache,如之前所述,这样的Cache分为多个set(组),每个组里面又有多个line/way(行),每个line里面又有多个字节。
对某个page进行操作时,会将page分配到cache里,这种分配是按照一定关系的。
假设page的大小为4KB,考虑物理地址;
cache的大小为2M,16384个4-Way SET,32 Bytes line,即32*4*16384=2M。
执行memset(0, 0, 4*1024)的话,这4KB内存在cache上会放在连续的0到127set中每个set的第1个line;
执行memset(1, 0, 4*1024)的话,这4KB内存在cache上会放在连续的128到255set中每个set的第1个line;
...
执行memset(128, 0, 4*1024)的话,这4KB内存在cache上会放在连续的0到127set中每个set的第2个line;
执行memset(129, 0, 4*1024)的话,这4KB内存在cache上会放在连续的128到255set中每个set的第2个line;
就是说第ith物理页面会与第(128*j+i)th个物理页面中Cache中占据同样的Cache Sets。Set满了之后,按照一定的算法 ,比如LRU算法(Least Recently Used algorithm)清除之前的数据。
以上说的是现象,产生上述现象的原因可以用下图来解释:
物理地址的位5-11是page中的偏移地址,7位,可以表示128个set;