【深度学习CPU(番外篇)——虚拟内存】

系列文章目录

1.《带你深挖计算机底层逻辑,打通你计算机基础知识的任督二脉》

2.《深度学习计算机底层原理,深度剖析存储器》

3.《基于内存全面理解高速缓冲存储器》

4.《深度学习计算机指令系统,彻底搞懂指令十大寻址方式》

5.《降维打击,带你深度学习CPU(上)》

6.《深度学习CPU(番外篇)——虚拟内存》


文章目录

  • 系列文章目录
  • 前言
  • 一、虚拟存储器的基本概念
  • 二、页式虚拟存储器
  • 三、段式虚拟存储器
  • 总结


前言

        虚拟存储器是由主存和辅存(外存、类似于磁盘磁带之类的外部存储设备)共同构成的,二者在硬件和系统软件的共同管理之下工作,对于应用程序员而言,虚拟存储器是透明的,并且他同时具有主存的速度和辅存的容量。

【深度学习CPU(番外篇)——虚拟内存】_第1张图片


 一、虚拟存储器的基本概念

        虚拟存储器将主存辅存的地址空间统一编址,形成一个庞大的地址空间,在这个空间内,用户可以自由编程,而不必在乎主存的容量和程序在主存中实际的存放位置。

        用户编程涉及到的地址称为虚地址或者逻辑地址(说白了就是假地址),虚地址对应的存储空间称为虚拟空间或者程序空间,而实际的内存单元的地址称为实地址或物理地址,实际地址对应的是主存地址空间,也成为实地址空间,虚拟内存要比真实的内存大很多。再结合我们上文当中所提到的“虚拟存储器就是主存(主存就是内存后面可能会交叉使用)和辅存共同构成的”,那么这句话到底是什么意思呢?其实很简单就是把内存本身拿过来,再把外存拿过来然后对他们的容量之和进行统一的编址,这样就会使得内存看起来很大了。

        为什么叫做虚拟内存,因为它本来就是一个假内存,他是由内存和外存合二为一拼凑成的。

【深度学习CPU(番外篇)——虚拟内存】_第2张图片

详解: 

  1. 如果大家还是不能明白的话,请看上图,这个就是我的计算机C盘(外存或辅存)当中的的文件,每一个文件都对应着一个地址,这就是虚拟地址,实际上都是不存在的,也就是这些地址在真实的内存当中是不存在的,他们仅仅存在于虚拟内存当中。
  2. 那么这个时候可能就会由小伙伴会问了,这个虚拟内存他存在的意义到底是什么呢?说白了就是扩大内存,那么他是怎么做到扩大内存的呢?
  3. 在CPU调用程序的时候,而程序是需要存放到内存当中才可以被CPU调用的,而且CPU是不可以直接访问外存(磁盘、磁带、光盘之类的外部存储设备)的,但是我们是不可能做到把所有的程序全部都调到内存当中的,况且内存也没有这个容量。
  4. 所以为了起到扩大内存的作用,我们就借助外存来扩充内存,我们把暂时不需要的程序存放到外存当中,先让CPU执行内存当中的程序,那么这个时候当CPU要执行的程序不在内存当中的时候,再去外存当中调取程序并且存放到内存中。
  5. 最后就通过CPU—内存—外存这样的体系构成了虚拟内存,也起到了扩大内存的作用。

总结:在这里有必要为大家讲解一下CPU执行程序时虚拟内存的具体功能

  1. 先将外存和内存的容量进行统一的编址,这个时候就会从逻辑上将内存和外存合为一体(然而并没有),这个时候就形成了虚拟内存的概念,这个时候我们所有的程序(程序由指令和数据共同组成)从逻辑上都存放在这个虚拟内存当中(现实中其实是一部分在内存中一部分在外存中),然后对这个虚拟内存统一编址(也就是对这些逻辑上存放在虚拟内存当中的程序分别进行编址)。
  2. CPU要执行某个程序的时候,会先从虚拟内存当中存放的程序进行寻找,当找到相应的程序以后,由于每一个程序在虚拟内存当中都有一个逻辑地址,这个时候操作系统会将逻辑地址转换为物理地址(至于具体时怎么转换的,我们稍后再将),这个时候CPU就可以根据程序在内存当中的物理地址找出想要执行的程序。
  3. 但是这个时候会出现一个问题,CPU在使用虚地址的时候,有辅助硬件找出虚地址和实地址之间的关联,找到实地址(物理地址),但是万一这个虚地址里面存放的程序压根就不再内存当中该怎么办?
  4. 也就是说CPU虽然在虚拟内存当中找到了想要执行的程序,但是很可惜,这个虚拟内存当中的程序并不在真是的内存当中,这个时候该怎么办呢?(CPU执行程序必须经过内存,无法经过外存直接访问)。
  5. 若不在主存当中的话,则将包含这个程序的一页或一段调入主存后再由CPU进行访问,如果这个时候主存已经满了,则采用替换算法置换主存当中的页面。位CPU想要执行的程序腾出空间。(至于什么是页和段咱们随后解释)。
  6. 虚拟存储器采用和Cache类似的技术,虚拟空间会将辅存当中经常访问到的数据副本(副本就是再拷贝一份)存放到内存当中去,但是缺页和缺段而访问辅存的代价是很大的,必须提高命中率,因此虚拟存储器采用全相联映射,每一个虚拟内存的需页面可以存放到内存当中的任何一个空闲位置。(缺页缺段就是之前提到的,CPU找到了虚地址但是虚地址对应的程序却不在主存当中,这个时候必须访问辅存,再把辅存中的程序调入内存,这种访问称为却缺页访问)。

二、页式虚拟存储器

        页式虚拟存储器以页为基本单位,虚拟空间与内存空间都被划分成同样大小的页(之所以称为页,是因为将内存和虚存划分成为无数个大小相同的区域,我们将这些区域称为页,那么段就是大小不同的区域,当然段相比于页还有很多的不同,我们随后介绍),内存的页称为实页、页框虚拟内存的页称为虚页,将虚拟地址分为两个字段:虚页号和页内地址。虚拟地址到物理地址的转换是页表实现的。页表是一张存放在主存当中的虚页号和实页号的对照表,他记录程序的虚页在调入主存的时候被安排在主存的位置,页表一般长期地永久地保存在内存当中。

        1.页表:

        有效位也被称为装入位,用来表示对应的页面是否在主存当中。若为1,则表示虚拟页已经从外存调入主存,此时页表项存放该页的物理页号;若为0,则表示没有调入主存,此时页表项可以存放该页的磁盘地址。

        脏位称为修改位,用来表示页面是否被修改过,虚拟内存的机制当中采用回写策略,利用脏位可以判断替换时是否需要写回磁盘。

        引用位也成为使用位,用于配合替换策略,也就是说发生缺页访问的时候当主存当中容量已满,需要将外存中的程序调入主存,需要将主存当中原有的一些页替换出去。

【深度学习CPU(番外篇)——虚拟内存】_第3张图片


        我说到这里的时候,如果不出意外的话很多小伙伴其实对于这部分的内容仍然是一头雾水,云里雾里的感觉,没关系,因为上面只是小试牛刀,下面才是真正的干货,做好准备,我们发车了,小伙伴可坐稳了。

【深度学习CPU(番外篇)——虚拟内存】_第4张图片

序言: 

        首先我在这里介绍几个非常重要的概念,大家务必掌握,否则很难理解后续内容。

  • 什么是页:将内存分成大小相同的几个块,要知道内存的本质上是一个存放字节序列的线性数组,操作系统将内存平均地分成大小相同的存储区,我们管这些存储区叫做页,注意必须是大小相同的才行(我们想象一下,我们日常生活中所说的页,是指书本中的页,书本中的每一页不就是大小相同的吗)。

【深度学习CPU(番外篇)——虚拟内存】_第5张图片

  • 操作系统将虚拟内存划分成大小相同的块叫做页面 ,将内存划分成大小相同的块,这种快就叫做页帧但是我们平常统称位 “ 页 ” ,这一点非常重要,请大家一定要牢记。
  • 接下来我们来解释什么叫做页号(页号也叫做页码),其实很简单,不用我说想必大家也可以理解了,大家再看书的时候第1页、第2页......,这就叫页号或者页码,我们的内存分成了好几块(页),总得有个标记吧,所以页号就诞生了。
  • 接下来我解释什么叫做页内地址(页内地址也叫做页偏移量),偏移量大家总不会陌生吧,就是在原来的基础之上增加若干个单位,就叫偏移量,比如说在3号页的基础上再向下访问两个偏移量就是5号页。
  • 最后一个重要的概念就是物理页号,物理页号其实和虚拟页号一个意思,但是这个里面存放着一个非常重要的信息,就是物理基地址,注意这里非常重要,一定要理解,刚才我们说了偏移量,要在基地址的基础上偏移,那么及地址在哪里呢?物理页号就是基地址。

【深度学习CPU(番外篇)——虚拟内存】_第6张图片

  1. 好了到了这里以后,我们就开始对CPU访问虚拟内存的具体过程进行介绍了,首先由页表基址寄存器记录着页表的首地址,以便于系统找到页表。
  2. 页表作为虚地址向物理地址转换的媒介,里面主体部分由两大部分装入位(有效位)和物理页号(物理基地址)。
  3. 当操作系统给出虚地址以后,会根据页表找到虚页号在页表当中对照的物理页号,并且根据有效位来判断虚地址对应的程序是否已经存放到内存当中,因为页表只能负责找到虚地址对应的物理地址,但是虚地址所在的程序是否在内存当中这个不能保证。
  4. 找到以后并且确认程序在内存当中以后,这个时候页表当中的物理页号(基地址)结合虚地址当中的页内地址(页偏移量)以后就会精准的得出我们的物理地址(整个过程非常类似我们的计算机指令的基址寻址方式,感兴趣的小伙伴们可以阅读我的上一篇文章《深度学习计算机指令系统》)。
  5. 那么有小伙伴可能又会问了,万一有效位为零(虚地址所在处的程序不在内存)怎么办呢?也就是操作系统位CPU找到了物理地址,但是发现里面是空的,该怎么办?这个时候操作系统会将不在内存当中的程序调入主存,然后CPU再对其进行访问。

页式存储器的优点:

        页面的长度固定,页表简单,调入方便。但他的缺点是由于程序不可能正好是页面的整数倍,最后一页的零头将无法合理利用而造成浪费,并且页不是逻辑上独立的实体,所以处理、保护、共享都不及段式存储器方便。

        可能由读者对于我刚才说的“不是逻辑上的实体”有所疑惑,简单来说,他不是一个完整的独立的实体,你可以想象一下,如果我把我刚写好的代码,平均每分成大小相同的页,那是不是意味着一些有着完整功能的代码段可能会被拆开,假如说我已两行代码为一页划分内存,那么一个具有完整功能的函数可能由十行,但却被分裂成了五页,所以这就不再是逻辑上独立的实体了,我这么说你明白了吗?


三、快表

1.概述

        这里的快表仍然属于页式存储器,但是由于内容太多而且不好理解,所以我单独地把它拿出来,作为一个主题,但是请读者理解,快表依然属于刚才页式存储器的一部分内容。

2.概念        

        首先什么是快表,快表就是将页表存放到Cache当中去,原来的页表是存放在内存当中的,当虚地址与物理地址进行转换的时候,是需要不断地访问内存的,我们要知道CPU访问内存的速度是远远慢于访问Cache的速度的,所以我们将存放在内存当中的页称为慢表(对,就因为他慢),存放在Cache当中的页表称为快表。

3.快表的工作原理

  1. CPU给出虚拟地址,然后由操作系统去查找快表,但前提是页表必须提前存放到Cache中,只有这样CPU才能查找快表。
  2. 顺利查找到快表以后,操作系统会将虚拟地址转换为物理地址,那么这个时候是不是就可以通过物理地址到主存当中去执行程序了呢?常规操作是这样的,但是既然页表可以由内存调入Cache中,那么物理地址对应的程序(内存块)是不是也可以调入Cache呢?毕竟能少访问主存一次就少访问一次,这样可以提高CPU执行的速度,何乐而不为呢?
  3. 所以操作系统通过Cache访问到虚地址对应的物理地址以后,直接到Cahce中访问物理地址所对应的内存块就可以了,当然前提是内存块必须提前由主存调入Cahce。

缺页访问:

  1. 那么这个时候可能会有小伙伴发现,之前的访问过程是由很多的前提的,比如要到Cache中访问快表,那万一这个时候的页表项(也表里面关于某一具体的虚地址像物理地址转换的内容,页表有很多内容其中一项叫做页表项)还在内存中没有调入到内存中怎么办呀,CPU通过物理地址直接到Cache中访问内存块,那万一内存块没有从内存中调入到Cahce中怎么办呀,这个时候就是我们说的缺页访问。怎么解决呢?很简单,见招拆招呗!
  2. 如果页表没有从内存中调入到Cache中,那么会由操作系统访问内存中的页表,然后将页表从内存调入内存即可。可这个时候万一又出现问题了,内存中也没有页表怎么办,内存中的页表也是操作系统在分配虚拟内存的时候就已经将对应关系写进去了,但是有些虚拟内存刚刚分配逻辑地址以后,操作系统还没来得及为其把虚地址与物理地址的对照关系(页表)写进内存可怎么办?只需要将主存中的空闲页拿出来,操作系统再写入即可,看我就说了简单吧,见招拆招呗!那万一主存中没有空闲页怎么办呐?很简单按照一定的算法将某一页替换掉就可以了,至于具体是什么算法我们下一篇文章为大家讲解。
  3. 如果页表项存在,并且也得到了物理地址,但是物理地址对应的内存块不在Cache中怎么办?只需要从Cahce中找出一个空闲块即可,如果没有空闲块同样的按照一定的算法将某一块替换出来即可。
  4. 到这里页表中的快表和慢表的基础内容我就讲完了,希望大家有所收获,具体过程我贴了课本上的一张图片供大家参考,这张图片里面的所有流程我都已经在上文当中讲过了。

【深度学习CPU(番外篇)——虚拟内存】_第7张图片


 四、段式虚拟存储器

        对于这里的短时虚拟存储器,和页式虚拟存储器有着极大的相似,只是在对于内存的划分上不同,首先内存被划分成的内存块的大小是不相同的,而且这些快是按照程序的自然分界来划分的,所以称为段。

        比如说我们平常所读的课文,里面的每一个自然段就是一个独立的个体,如果这么说还是不理解的话,可以举一个例子,比如说我们平常写代码写到的函数,每一个函数是一个独立的个体,具有独立的功能,那么段式虚拟存储器在划分内存的时候,就可以把每一个函数编译后形成的代码段和数据段进行独立的划分,这种划分形式大小虽然不一样,但是每一段都是一个程序的自然分界点,我这么说,你明白了吗?


总结

        这两种虚拟存储器之后其实还有一个页段式虚拟存储器,不过这个我们不打算考研的小伙伴不需要做出过多的了解,我们只需要了解前两种即可,感兴趣的小伙伴可以自行查阅资料,到这里的话,虚拟内存就为大家讲解完了,下一篇文章应该就能继续为大家讲解关于CPU的知识了。

        不打算考研的小伙伴很多知识是不需要掌握的,以后面试也好还是找工作也好都是不需要的,就比如说我们操作系统中的很多算法题目其实只需要了解去工作流程就可以了,但是在考研的时候是需要每一步都清晰地写出来的,包括运算过程,还有计算机组成原理也是如此,很多的包括中断、指令流、高速缓存的运算时间、效率、平均找道时间我们是不需要会运算的,但是考研却对这一部分的要求很高,所以相同的知识,对于考研和不考研的小伙伴来说,要求是不一样的。


你的支持就是我最大的动力,请问你学会了吗

你可能感兴趣的:(计算机底层原理,硬件工程,windows)