深入理解计算机系统——第一章 计算机系统漫游

计算机概论

第一章 计算机系统漫游

1.1 信息就是位+上下文

计算机系统所有信息都是由一串比特表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。

例如:

int a = 10; //当我们判断a属于什么数据类型时,可通过a的上下文获知

1.2 程序被其他程序翻译成不同的格式

预处理器
编译器
汇编器
链接器
hello.c
hello.i
hello.s
hello.o
可执行目标程序

预处理阶段:预处理器(cpp)根据预处理指令,修改原始的C程序。例如:

#include"stdio.h" //在预处理阶段,cpp会把stdio库中的代码添加进该文件

编译阶段:编译器将hello.i转换为hello.s,即c语言编译为汇编语言。

汇编阶段:汇编器(as)将hello.s翻译为机器语言指令,并把这些指令打包成一种叫做可重定位目标程序的格式,保留在hello.o文件中。

链接阶段:链接器负责将例如printf.o等单独预编译好了的目标文件合并到hello.o程序中,结果所得到的hello文件就是一个可执行目标文件。(极大地节约了计算机资源)

1.3 处理器读并解释储存在内存中的指令

1.3.1 系统的硬件组成

在这里插入图片描述

1、总线

贯穿整个系统的一组电子管道,称作总线,它携带信息字节并负责在各个部件间传递。通常总线被设计成传送定长的字节块,也就是字。

2、I/O设备

I/O设备是系统与外部世界的联系通道。上图包括的I/O设备有:键盘、鼠标、显示器以及用于长期储存数据和程序的磁盘驱动器。

每个I/O设备都通过一个控制器或适配器与I/O总线相连。控制器是主板上的芯片组,适配器则是一块插在主板插槽上的卡。

3、主存

主存是一个临时存储设备,在处理器执行程序时,用来存放程序和程序处理的数据。物理上,主存是一组动态随机存取存储器(DRAM);逻辑上,存储器是一个线性的字节数组,每个字节都有其唯一的地址,这些地址是从零开始的。

4、处理器

中央处理单元(CPU),简称处理器,是解释(或执行)存储在主存中指令的引擎。处理器的核心是一个大小为一个字的存储设备(或寄存器),称为程序计数器(PC)。在任何时候,PC都指向主存中要执行的下一条指令,即PC只存储了下一条指令的地址。通电状态下,处理器一直在执行程序计数器指向的指令,执行完后再更新程序计数器,使其指向下一条指令。

处理器按照指令集架构模型来操作的。在这个模型中,指令按照严格的顺序执行,每一条指令都围绕着主存、寄存器文件和算术/逻辑单元(ALU)进行。寄存器文件是一个小的存储设备,由一些单个字长的寄存器组成,每个寄存器都有唯一的名字。ALU负责计算新的数据和地址值。

1.3.2 运行hello程序

运行hello程序整体可分为两步:

第一步是通过键盘在shell中输入"./hello",shell程序将会把字符逐一读入寄存器,再把它们放到内存中(下面第一张图),当我们敲回车键时,shell就会结束输入,然后执行一系列指令加载可执行的hello文件,这些指令将hello目标文件中的代码和数据通过处理器复制到主存上。利用直接存储器存取技术DMA,数据可不通过处理器直接从磁盘到达主存(下面第二张图)。
在这里插入图片描述
在这里插入图片描述

第二步,一旦目标文件hello中的代码和数据被加载到主存上,处理器就开始执行hello程序的main程序中的机器语言指令。这些指令将“hello, world\n”字符串中的字节从主存上复制到寄存器文件,再从寄存器文件复制到显示设备,最终显示在屏幕上。

在这里插入图片描述

1.4 高速缓存

为什么要用到高速缓存?

hello程序的机器指令最初存放在磁盘上,当程序加载时,它们被复制到主存;当处理器开始运行程序时,指令又从主存复制到处理器,这些复制极大的减慢了程序“真正”的工作。

处理器从寄存器文件中读取数据比从主存中读取几乎要快100倍,针对这种差异,系统设计者采用了更小更快的存储设备,称为高速缓存存储器(cache memory),作为暂时的集结区域,存放处理器近期可能会需要的信息。高速缓存分为不同级别,例如L1与L2,L1的容量比L2小,但访问速度更快。高速缓存是用一种叫静态随机访问存储器(SRAM)的硬件技术实现的。

在这里插入图片描述

1.5 存储设备形成层次结构

在处理器和一个较大较慢的设备之间插入一个更小更快的存储设备可以极大地提高程序运行效率。每个计算机系统中的存储设备都被组成为一个存储器层次结构,从上至下,设备的访问速度越来越慢,容量越来越大,并且每个字节的造价越来越便宜。

在这里插入图片描述

1.6 操作系统管理硬件

当在shell上运行hello程序时,shell和hello程序并没有直接访问键盘、显示器、磁盘或者主存,而是依靠操作系统提供的服务。

所有应用程序对硬件的操作尝试都必须通过操作系统。操作系统有两大基本功能:①防止硬件被失控的应用程序滥用;②向应用程序提供简单一致的机制来控制复杂而又大不不同的低级硬件设备。

操作系统通过几个基本的抽象概念(进程、虚拟内存和文件)来实现这两个功能。文件是对I/O设备的抽象表示,虚拟内存是对主存和磁盘I/O设备的抽象表示,进程则是对处理器、主存和I/O设备的抽象表示。

在这里插入图片描述

1.6.1 进程

进程是操作系统对一个正在运行的程序的一种抽象。我们的电脑在使用过程中可以操作多个应用程序并不意味着我们的处理器可以同时运行多个进程,单处理器在一个时刻只能执行一个程序。我们所看到的并发运行是处理器在进程间来回切换来实现的,这种交错执行的机制称为上下文切换

操作系统保持跟踪进程运行所需的所有状态信息,叫做上下文。当操作系统决定要把控制权从当前进程转移到某个新进程时,就会进行上下文切换,即保存当前进程的上下文、恢复新进程的上下文,然后将控制权传递到新进程。

在这里插入图片描述

1.6.2 线程

在现代系统中,一个进程可以由多个称为线程的执行单元组成,每个线程都运行在进程之中,并共享同样的代码和全局数据。相较于多进程,多线程更容易共享数据。

1.6.3 虚拟内存

虚拟内存是一个抽象概念,它为每个进程提供一个假象,即每个进程都在独占地使用主存。每个进程所使用的存储器都称为虚拟地址空间。地址空间最上面的区域是保留给操作系统中的代码和数据的,地址空间的底部区域存放用户进程定义的代码和数据。(下图中的地址从下往上增大的)


• 程序代码和数据。对所有进程来说,代码是从同一固定地址开始,紧接着的是和C全局变量相对应的数据位置。代码和数据区是直接按照可执行目标文件的内容初始化的。

• 堆。代码和数据区后紧随着的是运行时堆。代码和数据区在进程一开始运行时就被指定了大小,与此不同,当调用像 malloc free 这样的标准库函数时,堆可以在运行时动态地扩展和收缩。

• 共享库。大约在地址空间的中间部分是一块用来存放像标准库和数学库这样的共享库的代码和数据的区域。

• 栈。位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数调用。和堆一样,用户栈在程序执行期间可以动态地扩展和收缩特别地,每次我们调用一个函数时,栈就会增长;当一个函数返回时,栈就会收缩。

• 内核虚拟内存。地址空间顶部的区域是为内核保留的。应用程序不能读写这个区域的内容或者直接调用内核代码定义的函数,只能通过调用内核来执行某些操作。

1.6.4 文件

文件就是字节序列。每个I/O设备,包括磁盘、键盘、显示器,甚至网络,都可以看成是文件(当我们想要获取某些信息时,就可以读取这些文件)。系统中的所有输入输出都是通过使用一小组称为Unix I/O的系统函数调用读写文件来实现的。

1.7 系统之间利用网络通信

从一个单独的系统来看,网络可视为一个I/O设备。当系统从主存复制一串字节到网络适配器时,数据流经网络到达另一台机器。相似地,系统可以读取从其他机器发送来的数据,并把数据复制到自己的主存。

在这里插入图片描述

1.8 重要主题

1.8.1 Amdahl 定律

定律思想:当我们对系统的某个部分加速时,其对系统整体性能的影响取决于该部分的重要性和加速程度。若系统执行某个应用程序需要时间为Told。假设该应用程序某部分所需执行时间与该时间的比例为α,而该部分性能提升比例为k。即该部分初始所需时间为αTold,现在所需时间为(αTold)/k。因此,总的执行时间应为:

T n e w = ( 1 − α ) T o l d + ( α T o l d )/ k = T o l d [ ( 1 − α ) + α / k ] T_{new}=\text{(}1-\alpha \text{)}T_{old}+\text{(}\alpha T_{old}\text{)/}k=T_{old}\left[ \text{(}1-\alpha \text{)}+\alpha /k \right] Tnew=1αTold+αTold/k=Told[1α+α/k]
由此,可以计算加速比S=Told/Tnew为:

S = 1 ( 1 − α ) + α / k S=\frac{1}{\text{(}1-\alpha \text{)}+\alpha /k} S=1α+α/k1

1.8.2 并发与并行

并发:计算机通过快速切换进程来实现进程的同时运行。

并行:利用并发来使系统运行的更快。举一个简单的例子:当你家来客人时你妈喊你泡茶,你需要洗杯子、茶壶并烧水,你可以先烧水,在烧水的时候洗杯子和茶壶,使效率最大化。

  1. 线程级并发

线程级并发指一台电脑可以同时具有多个线程,这种并发执行只是模拟出来的,是通过使一台计算机在它正在执行的进程间快速切换来实现的。

多核处理器:将多个CPU集成到一个集成电路芯片上。多核处理器中的每个核都有自己的L1和L2高速缓存。L1分为两部分,一个负责保存最近取到的指令,一个负责存放数据。这些核共享更高层次的高速缓存,以及到主存的接口。

在这里插入图片描述

超线程:也称同时多线程,是一项允许一个CPU执行多个控制流的技术。具有超线程的处理器可以在单个周期的基础上决定要执行哪一个线程。例如执行某个线程需要等某些数据加载到高速缓存中,那CPU就可以继续去执行另一个线程。

  1. 指令级并行

在较低的抽象层次上,现代处理器可以同时执行多条指令的属性称为指令级并行。在以前,计算机执行一条指令需要20多个周期,但现在计算机可以保持每个时钟周期2~4条指令的执行速率。原因是计算机将执行一条指令所需的活动划分为不同的步骤,并将处理器的硬件组织成一系列的阶段,每个阶段执行一个步骤。这些阶段可以并行地操作,用来处理不同指令的不同部分。

  1. 单指令、多数据并行

在最低层次上,许多现代处理器拥有特殊的硬件,允许一条指令产生多个可以并行执行的操作(并行执行多个该指令),这种方式成为单指令、多数据,即SIMD并行。这种并行方式多适用于提高处理影像、声音和视频数据应用的执行速度。

1.8.3 计算机系统抽象的重要性

抽象性可以使我们更好地理解计算机,无需了解计算机内部结构便可以使用计算机。

在学习操作系统的过程中,除文件、虚拟内存和进程外,还有虚拟机这个抽象。虚拟机提供对整个计算机的抽象,包括操作系统、处理器和程序。(虚拟机的提出来源于人们对同一计算机运行不同操作系统的需求)

像、声音和视频数据应用的执行速度。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值