CPU:执行指令,控制计算机操作,协调计算机处理数据。
处理器:整合cpu芯片上的各种电路和模块(运算器、控制器、寄存器)
内核:负责管理和控制计算机的硬件资源,提供系统调用和管理进程的能力。
三者之间的关系:CPU执行指令需要调用操作系统的代码,而这些代码都存放在内核中,因此处理器和CPU的运行都受到内核的管理和控制。
早期的没有复杂的图形处理,所以CPU的核心频率也不高,所以都连接在同一个总线上。由于后来的巨大需求,为了协调CPU、内存和高速的图形处理,人们设计了北桥芯片,高速处理数据。但是实际中也有一些低速设备,如果还在北桥芯片上跑就显得有点浪费资源。所以人们设计了南桥芯片,用于跑一些低速设备,键盘、鼠标、U盘。
从2004年开始,CPU的开发已经达到物理瓶颈,CPU核心频率定格在4GHZ。但是由于一些特殊需求/对CPU更大需求频率,人们从另外一个角度来提升CPU 的速度,就是增加CPU的数量。其中一种形式对称多处理器,每个CPU在系统中的地位是一样的,固称对称。理论上CPU的运算速度该和CPU的数量成正比,但是实际并非如此,程序并不能拆分成多个完全不相干的子问题。正如一个女人可以十个月生一个孩子,但是是个女人并不能在一个月生一个孩子。
但多处理器还是非常有用的,一些大型数据库和服务器上他们就可以处理大量的数据访问,而这些访问都是独立的。
多核处理器:本来是一个处理器就配套一些相关的部件,但是多核处理器将多核打包成一个处理器,并且共用部件,价格也比单核贵不了多少。
编译器:源代码——>预处理器——>编译器——>目标代码——>链接器——>可执行程序
汇编器:将汇编语言翻译成机器语言,生成目标文件。
上图为计算机的软件结构体系。层次之间需要相互通信,通信需要规定的协议,我们称之为接口。接口的上层是使用者,下层是提供者。理论上只要遵循这个接口,每个层次都是可以修改或替换的。除了硬件和应用程序,其他都是所谓的中间层。
开发工具与运用程序是一个等级的,他们都是调用的同一个接口,操作系统的应用程序编程接口。运用程序的提供者是运行库,什么样的运行库提供什么的api。如Windows32提供的是Windows api。
操作系统提供抽象接口,管理硬件资源。
CPU比较昂贵,如果一颗CPU只跑一个程序,那就很浪费。于是人们编写了一个方法,用来监控程序,当程序不适用CPU时,监控就把另外在等待的程序启动,是的CPU充分利用起来,这种方法被称为多道程序。不过这种方法使得程序之间不分轻重缓急,比较粗力度。于是聪明的人类设计了另外一种方法,每个程序在运行一段时间之后就主动让给其他程序来运行,这样就能保证大多数程序能在单位时间内多能得到运行。由于程序之间的时间是按毫秒计算,所以对于愚蠢的人类并没有多大影响,这种程序协作模式叫分时系统。如果一个程序在执行一个耗时很长的计算,一直霸占CPU,进入到一种死循环,那就很容易荡机。开始的应用都还比较低端,所以分时系统还能应付。随着需求的增加,出现了多任务系统,操作系统接管了所有的硬件资源,并且系统运行在一个受硬件保护的。
所有的应用程序都以进程的方式运行在一个比操作系统低的级别,每个应用程序都有自己独立的地址空间,使得进程之间的地址相互隔离。CPU由系统通过优先级分配,但如果程序运行时间超出就会被系统暂停,操作系统会将CPU分给次等的程序运行,这种方式即为抢占式。
硬件驱动,它是操作系统的一部分,和操作系统一个特权级,但是又相互独立。硬件设备多如牛毛,他们的使用规范都是有厂商统一规范好的,凡是根据产商提供的接口和框架开发的程序都可以在操作系统上运行。
硬盘的存储单位为扇区,每个扇区单位为512个字节。一个硬盘往往有多个盘片,每个盘片分为两面,每个盘片按照同心圆分为多个磁道,每个磁道分为多个扇区。每个同心园的周长不一样,如果按照每个磁道都有相同数量的扇区,那么外围的磁道数量势必稀疏,这样就比较浪费空间。但是扇区的数量不一样就很难管理,所以人们提出一种LBA的方式,磁盘中所有的扇区从0开始编号,一直到最后一个扇区,又叫逻辑扇区。
在Linux系统中,我们要读取文件的前4096个字节,我们会使用一个read的系统调用来实现,文件系统收到请求后,判读出文件属于1000号逻辑扇区到1007逻辑扇区,然后系统向硬盘驱动发出一个读取逻辑扇区为1000开始的8个扇区的命令。
磁盘实体示意图:
磁盘逻辑示意图:
如,一个硬盘有2个盘片,每个盘面分为65536磁道,每个磁道分为1024个扇区,每个扇区有512个字节。那么磁盘容量为:2*2*65536*1024*512=137438953472个字节(128G)。
进程的目标从逻辑上看来都是希望每个进程都可以独占资源。抢占式机制对于反应过慢的人类来说,他们是同时进行的,但是对于电脑来说是分时间片来进行的。
操作系统多任务功能是的CPU能够在多个进程之间很好的共享,从进程的角度看它独占了CPU。I/O抽象模型也很好的实现了I/O设备的共享和抽象。那么剩下的就是主存问题,也就是内存分配问题。
举例:如果计算机有128M,A程序运行需要10M,B100M,C20M,A和B同时运行,前10M分给,10-110M分给B,这样分配会存在很多问题。
地址空间不隔离:所有程序都直接访问物理地址,地址不隔离,恶意程序很容易改写其他程序的内存数据,达到破坏的目的。
内存效率低:由于没有有效的内存管理机制,通常需要一个程序执行时,监控程序就将整个程序装入内存然后开始执行。如果我们突然需要执行C程序,那此时内存是不够运行的。如果换A程序的数据,内存还是不够,这时需要将B数据暂时存放的磁盘,等需要的时候再读取回来,这一来一回需要大量的转换数据空间,导致效率十分低下。
运行程序的地址不确定:因为程序每次需要装入运行时,我们都需要给他分配足够大的空间,而这块物理地址是不确定的。
我们可以通过虚拟地址,通过一些映射方法和物理地址做映射,可以保证任意一个程序的内存物理地址不会跟其他地址有重复。
除程序间通信部分外,程序需要简单的执行环境、单一的地址空间、有自己的CPU就好像一个进程一个计算机,进程间完全独立运行。
地址分为虚拟地址空间、物理地址空间。其中,物理地址空间是实实在在存在的,每个计算机只有一个;虚拟地址空间是虚拟的、想象出来的地址空间,每个进程都有并且只能访问自己的虚拟地址空间【使进程隔离】。
最开始时使用。就是使程序需要的虚拟地址空间与物理地址空间一一对应映射。
虽然解决了地址空间不隔离、程序运行地址不确定,但是对于内存的优化问题还是没有解决,如果内存不足,被换入换出的是整个程序从而造成大量磁盘访问操作,影响运行速度。
根据程序的局部性原理,一个时间段内可能只是频繁使用一小块数据,可以使用更小粒度的分割、映射方法:分页。
分页的基本方法:将地址空间分为固定大小的页,每一页由硬件决定,或是硬件支持多种页大小、操作系统决定。
虚拟空间的页:虚拟页(VP:Virtual Page)
物理内存的页:物理页(PP:Physical Page)
磁盘中的页:磁盘页(DP:Disk Page)
上图中VP2和VP3不存在内存中,若进程用到这两页时硬件就会捕获到这个消息,这种情况称为页错误。
解决:操作系统接管进程将VP2和VP3从磁盘读出装入内存,再将装入内存中的这两页与VP2、VP3重新建立映射关系。
虚拟存储的实现需要硬件的支持,不同CPU是不同的,但有一个必要的部件MMU(一般集中在CPU内部不以独立部件存在)进行页映射。