网站建设视频教程php,长治在百度做个网站多少钱,莘县做网站推广,湛江专业网站建设页表基本原理
页表主要用来将虚拟地址映射到物理地址#xff0c;在使用虚拟地址访问内存时#xff0c;微处理器首先将虚拟地址拆分成页号和页内偏移量#xff0c;然后使用页号在页表中查找对应的物理页框号#xff0c;将物理页地址加上页内偏移量#xff0c;得到最终的物…页表基本原理
页表主要用来将虚拟地址映射到物理地址在使用虚拟地址访问内存时微处理器首先将虚拟地址拆分成页号和页内偏移量然后使用页号在页表中查找对应的物理页框号将物理页地址加上页内偏移量得到最终的物理地址。 32位系统中当页大小为4KB时如要覆盖4GB内存需要1M个页项如果页项是连续的每个页项占4字节的话页表总共需要4MB。
虚拟地址组成
20位12位页号页内偏移
4MB如果在进程运行前都准备好对于进程来说空间占用太大了。可以考虑用多级页表实现动态分配假如分两级每级各占10比特
10位10位12位页目录项Page Directory EntryPDE页表表项Page Table EntryPTE页内偏移Page Offset
一个页目录项可以覆盖210个页也就是1MB内存。
cache基本原理
cache是为了缓存经常用到的内存数据。 先不考虑缓存的是物理地址还是虚拟地址。
cache以cache line为单位进行缓存如果cache line是8字节那这8字节会一起加载到cache中要失效也是一起失效。
直接映射缓存
下图是一个64字节大小的cachedata array中每行是一个cache linecache line有一个D位表示数据是否dirty。
cache将地址分为3部分tag index offset。
offset是地址在cache line中的偏移该例中cache line是8字节所以需要3比特。 index是地址在data array中的索引该例中cache size是64字节cache line是8字节所以data array有8行index需要3比特。
地址 0x14 和 0x654 都映射到cache中一个位置那怎么区分存储的是哪个数据呢靠比较tag。 1个tag对应1个cache line所以offset位不需要考虑对比tag的时候已经定位到具体的行了index位也是固定的了所以tag只需要记录除offset和index外的位该例中是32-3-326位。tag array和data array容量相同并且一一对应如果tag是 0x19就表示当前cache line的起始地址是 0x650。
26位3位3位tagindexoffset
我们可以从图中看到tag旁边还有一个valid bit用来表示cache line中数据是否有效。当系统刚启动时cache中的数据都应该是无效的。所以上述比较tag确认cache line是否命中之前还会检查valid bit是否有效。只有在有效的情况下比较tag才有意义。如果无效直接判定cache缺失。
图中这种方式叫直接映射缓存它对地址的缓存是循环的0x00,0x40,0x80…开始的8字节都映射到同一个cache line中。 系统启动后当我们访问 0x00 地址时cache会缺失然后数据会从主存加载到cache中第0行cache line。当我们访问0x40地址时依然索引到cache中第0行cache line由于此时cache line中存储的是地址0x00地址对应的数据所以此时依然会cache缺失。然后从主存中加载0x40地址数据到第0行cache line中。同理继续访问0x80地址依然会cache缺失。这就相当于每次访问数据都要从主存中读取访问0x40地址时就会把0x00地址缓存的数据替换。这种现象叫做cache颠簸cache thrashing。
多路组相连缓存
针对这个问题引入多路组相连缓存。我们首先研究下最简单的两路组相连缓存。 data array中竖着叫路横着叫组。将64字节cache分成两路之前data array有8行现在有两个data array所以只有4行了index也只需要2比特了。tag还是占除index和offset外的所有位。 根据index找到是哪组然后将组内的所有cache line对应的tag取出来和地址中的tag部分对比如果其中一个相等就意味着命中。就像链表一样。 据说会降低cache颠簸的频率。
直接映射缓存是组相连缓存的一种特殊情况每个组只有1个cache line它只有1路。全相连缓存是另一种特殊情况它只有1组。
cache size 2index位数 * 路数 * 2offset位数 路数 * 2(index位数offset位数)
cache组织方式
PIPT和VIPT
如果cache缓存的是物理地址称为PIPTPhysically Indexed Physically Tagged。CPU发出的虚拟地址经过MMU转换成物理地址再将物理地址发往cache控制器查找确认是否命中cache。
如果缓存的是虚拟地址称为VIVTVirtually Indexed Virtually Tagged。虚拟地址直接送到cache控制器如果cache hit直接从cache中返回数据给CPU如果cache miss则把虚拟地址发往MMU经过MMU转换成物理地址从主存读取数据。
缓存命中的时候相比PIPTVIVT少了虚拟地址到物理地址的转换。但是VIVT有歧义和别名的问题。 歧义是指不同的数据在cache中具有相同的tag和index。假设A进程虚拟地址0x4000映射物理地址0x2000B进程虚拟地址0x4000映射物理地址0x3000。当A进程运行时访问0x4000地址会将物理地址0x2000的数据加载到cache中。当切换到B进程的时候B进程访问0x4000会怎样当然是会cache hitB进程本来想得到物理地址0x3000对应的数据但是却由于cache hit得到了物理地址0x2000的数据。进程切换的时候flush cache可以避免歧义问题。 同一个物理地址的数据被加载到不同的cache line中就会出现别名现象。比如虚拟地址0x2000和0x4000二者在不同的cache line中都映射到相同的物理地址0x8000这意味着进程既可以从0x2000读取数据也能从地址0x4000读取数据。这是由页表的多对一导致的。一个解决方法是让映射到同一物理地址的虚拟地址在cache中也有相同的地址。但这只对直接映射缓存有效细节后面会详细说。
VIPT
为了提升cache查找性能我们不想等到虚拟地址转换物理地址完成后才去查找cache。因此我们可以使用虚拟地址对应的index位查找cache与此同时(硬件上同时进行)将虚拟地址发到MMU转换成物理地址。二者都完成时比较cache line对应的tag和物理地址以此判断是否命中cache。我们称这种方式为VIPT(Virtually Indexed Physically Tagged)。
cache line对应的tag可以使用完整的物理地址。此时不会有歧义问题比如之前例子中B进程访问0x4000时会发现tag不同于是cache miss。由于物理地址和虚拟地址的低12位是相同的cache line对应的tag可以只存物理地址的高20位对比的时候将其加上地址的低12位便是完整的物理地址了。
别名问题是因为虚拟地址和物理地址多对一导致的只要物理地址相同的虚拟地址也在相同的cache地址中就不会有问题。也就是让这些虚拟地址的index位和offset位相同。 当index位和offset位之和不大于12时各个虚拟地址的低12位和物理地址的低12位本就相同所以index位和offset位也必然相同此时不存在别名问题。 当index位和offset位之和大于12时为同一物理地址分配多个虚拟地址时则要保证虚拟地址的index位和offset位相同可以让其全为0也就相当于按“cache size/路数”对齐了。
这种方法在VIVT中只对直接映射缓存有效。因为在多路组相连缓存中对应同一物理地址的多个虚拟地址会映射到同一组中如果是Virtually Tagged因为tag不同它们会定位到不同的路中。
PIVT
不存在因为PIVT方式首先要通过MMU转换成物理地址然后才能根据物理地址index域查找cache既然都有了物理地址干嘛不直接用PIPT。
参考
Cache的基本原理 Cache组织方式