A Tour of Computer System计算机系统漫游

        刚开始看会觉得比较晦涩难懂无趣,但是看完会有一个基本了解,对应课本第一章知识点,或有遗漏请见谅 

从hello程序进入计算机系统 

编写第一个c语言文件

#include <stdio.h>
using namespace std;
int main()
{
    printf("Hello,World!\n");
    return 0;
}

保存得到后缀为.c的文件 -----> hello.c

在终端运行指令

linux$ gcc -o hello hello.c

 生成一个可执行程序 hello

编译系统的处理过程(Compilation System) 

四个阶段

  1. 预处理
    1. 读取文件hello.c
    2. 预处理器根据#开头的代码修改原始程序
      1. 如例子,读取stdio.h头文件中的内容
      2. 将其中的内容直接插入到源程序中
      3. 结果得到另一个c程序文件,该文件通常以 .i 结尾(hello.i)
  2. 编译
    1. 将hello.o 文件翻译成 hello.s 文件
    2. 包括词法分析,语法分析,语义分析,中间代码生成以及一系列中间操作
  3. 汇编
    1. 汇编器根据指令集将汇编程序 hello.s 翻译成机器指令
    2. 把一系列的机器指令按照固定的规则进行打包,得到可重定位目标文件 hello.o(二进制文件)
  4. 链接
    1. 负责把 hello.o 和 printf.o 进行合并
    2. 得到可执行文件 hello 存放在系统磁盘(disk)上

为什么要理解编译系统如何工作的

  1. 优化程序性能,对机器执行的代码有基本了解
  2. 理解链接过程中出现的错误
  3. 避免安全漏洞,理解数据和控制信息在程序栈上是如何存储的

 计算机系统硬件组成

中央处理单元(CPU,处理器) 

  1. PC:英文Program Count,程序计数器,大小为一个字的存储区域(一个字的大小:32-bit 1word=4Byte ; 64-bit 1word=8Byte),存储某一指令的地址,处理器在不断的处理PC指向的指令,然后更新PC指向下一条指令(不一定相邻)
  2. 寄存器文件:英文Register File,CPU内部的一个存储设备,由一些单字节的寄存器构成,每个寄存器都有自己的名字,可以理解为一个临时存放数据的空间
  3. ALU:英文Arithmatic/logic Unit,复制寄存器中保存的值,进行算术运算,得到的结果返回到寄存器中,覆盖原来的数据

内存(主存,Main Memory)

  1. 功能:处理器在执行程序时,内存主要存放程序指令以及数据
  2. 物理上讲,内存是由随机动态存储器芯片组成
  3. 逻辑上讲,内存可以堪称一个从零开始的大数组,每个字节都有相应的数据地址

总线(I/O bridge)

  1. 数据总线,进行数据传递,负责将信息从一个部件传递到另一个部件,如内存和处理器之间通过总线进行数据传递
  2. 通常被设计成传递固定长度的字节块,也就是字(word),各个系统中的字是多少字节不一致

输入输出设备

  • 每一个输入输出设备都通过一个控制器或者适配器与IO总线相连
  • 鼠标,键盘,磁盘,显示器等等

 控制器与适配器

  1. 两者主要区别是封装方式
  2. 功能:在IO设备与IO总线之间传输数据

如何运行可执行程序

        打开一个shell程序(命令解释程序,输出一个提示符来等待命令行的输入,然后执行这个命令,如果命令行的第一个单词不是内置的shell命令,shell就会假设这是一个可执行文件的命令,进行加载并运行),输入相应可执行程序的文件名 


hello.c文件执行过程

  1.  键盘输入`./hello.c`的字符串,闪烁的hello字符串表示键盘输入
  2. shell程序会将输入的字符串逐一读入寄存器(CPU中的Reg)
  3. CPU(处理器)会将hello这个字符串放入内存中
  4. 按下回车键,shell程序知道命令的输入完成,执行一系列的指令来加载可执行文件hello
  5. 这些指令将hello中的数据从磁盘复制到内存,数据(要显示输出的`Hello,World!\n`),利用DMA技术,数据不经过处理器直接从磁盘加载到内存
  6. . 当数据加载到内存中,处理器(CPU)开始执行main函数中的代码,CPU将会将`Hello,World!\n`这个字符串从内存复制到寄存器文件,然后再复制到显示设备,最终显示在屏幕上

缓存器(Cashes Matter) 

  1. 大容量的存储设备的存取速度比小容量的慢
  2. 运行速度更快的价格要高于低俗设备的价格
  3. 内存比寄存器要大得多,所以从内存上读取一个字的时间开销比从内存中读取的花销大1000万倍
    1. 解决方案:在寄存器文件和内存之间引入了高速缓存(cache)
    2. 高级的处理器一般为三级高速缓存:L1 cashe,L2 cashe,L3 cashe
      1. L1 cashe 的访问速度几乎与寄存器一致,容量大小为数万字节
      2. L2 cashe的访问速度是L1 cashe 的1/5,容量大小为数十万到百万字节之间
      3. L3 cashe的访问速度最慢,容量也更大


 

计算机系统信息存储层次结构 

  1.  从上到小,访问速度越来越慢,每字节的造假也越来越便宜
  2. 主要思想:上一层的存储设备是下一层的存储设备的高速缓存
  3. 可以利用存储设备的层次结构来优化程序的性能

操作系统(The Operating Syetem Manages Hardware)

 理解成应用程序和硬件之间的中间层,所有应用程序对硬件的操作都必须通过操作系统来完成。

设计目的:

  1.  防止硬件被失控的应用程序滥用  
  2. 操作系统通过通一的机制来控制复杂的底层硬件

抽象概念:

  1. 文件是对IO设备的抽象
  2. 虚拟内存是对内存和磁盘IO的抽象
  3. 进程是对处理器,内存和IO设备的抽象


进程(Process)

  1. 通过hello进程来理解进程的概念
    1. 场景:只有两个并发的进程,shell进程和hello进程
    2. 刚开始只有shell进程在运行(在等待命令行输入)
    3. 通过shell进程来执行hello进程时
      1. 计算机的动作:请求--->shell进程----通过系统调用(system cell)---->执行请求---->将”控制权“传递---->操作系统---->保持shell的上下文 and 创建一个新的hello进程及其上下文---->将“控制权”传递---->hello进程----执行结束---->操作系统恢复shell进程上下文----将“控制权”传递---->shell进程,继续等待下一命令
      2. (控制权的传递流程:shell进程,操作系统,hello进程)
    4. 上下文(context)
      1. 操作系统会跟踪进程运行中所需要的所有状态信息,这种状态称为上下文,例如当前PC和状态寄存器中的值,以及内存中的内容等等
  2. 现在操作系统中,一个进程由多个线程组成,每个线程都运行在进程的上下文中,共享代码和数据,线程成为越来越重要的编程模型

虚拟内存

  1. 它为每个进程提供了一个假象,每个进程都在独自占用整个内存空间,每个进程看到的内存都是一样的,我们称为虚拟地址空间
  2. 虚拟内存,从小到大,从0开始,最大容量受CPU地址长度限制(图示为什么是0 - 2^48-1?# x86-64处理器(CPU)只有48位虚拟地址空间,剩下的空间保留给内核)

空间分布:

  1. 读写数据区域(全局变量) and  只读区域:
    1. 作用:存放程序的代码和数据
    2. 内容:从可执行目标文件中加载来的
    3. 对所有的进程来说,代码都从固定的地址开始,例如c语言中的全局变量存放在这个区域
  2. 堆(heap)
    1. c语言中的molloc函数就是在堆区开辟只当的空间大小,但是堆可以在运行的时可以动态扩展和收缩
  3. 共享库的存放区
    1. 主要存放c语言的标准库和数学库这种共享库的代码和数据
  4. 用户栈(user stack)
    1. 每一次程序进行函数调用的时候,栈就会增长;函数执行完毕时,栈就会收缩
    2. 栈的增长方向:从高地址到低地址
  5. 顶部空间,为内核保留的区域
    1. 对应用程序不可见,不能调用函数,不能读写数据

Linux 系统哲学思想 :一切皆为文件

        所有的IO设备(鼠标,键盘,磁盘,显示器,甚至网络)都可以看成文件,系统的输入输出都可以通过读写文件完成。
        从系统的角度来看,网络设备也可以看作一个IO设备       ​​​​​


如何通过网络在远程主机上执行hello程序(web服务器)

  1. 利用telnet通过网络远程运行hello,由于telnet的安全性问题,目前ssh的连接方式更普遍
  2. 流程
    1. 在本地ssh客户端==输入hello字符串==并且==敲入回车==后----通过网络---->将字符串发送到ssh服务端---->ssh接受到字符串---->将字符串传送给远程主机上的shell程序---->shell程序负责hello程序的加载---->运行结果返回到ssh的服务端---->将程序的运行结果发送给ssh的客户端---->在屏幕上显示运行结果

 阿姆达尔定律(Amdahl's Law)

S=\frac{T_{old}}{T_{new}} =\frac{1}{(1-a)+\frac{a}{k}}

  1. 主要思想:对系统某一部分进行加速时,被加速部分的加速程度和重要性影响整体系统性能的关键因素
  2. 可加速部分为a,不可加速的部分就是1-a,可加速部分提升性能比例为k
  3. 例子
    1. 当a=0.6,k=3时,S=\frac{1}{0.4}+\frac{0.6}{3}
    2. 当k->正无穷时,S=\frac{1}{1-a}=\frac{1}{0.4}=2.5,说明 如果要把计算机性能优化两倍那就要把大部分组件优化。

获得更高的计算能力

  1. 线程级并发
  2. 指令集并行
  3. 单指令,多数据并行

 多核处理器的组织结构

  1. 以四核处理器为例,举其中两个个CPU为例,其他两个个用省率号代替
  2. 每个CPU核心都有自己的 寄存器组 L1 cashe 和 L2 cashe (高速缓存区),四个CPU核心共用一个L3 cashe,四个CPU核心集成在一个芯片上,通过增加CPU的核心数可以提高系统的性能

 超线程(Hyperthreading)也称同时多线程

  1. 如果每个核心可以执行两个线程,那么四个核心就可以并行执行8个线程
  2. 单个CPU的核心如何实现超线程
    1. CPU内部PC(程序计数器)和Reg(寄存器文件)有多个备份,而浮点运算部件(AU)只有一个
    2. 常规单线程处理器在做线程切换时,大概需要20000个时钟周期,而超线程可以在单线程的基础上决定执行哪一个线程,CPU可以更好的处理资源,当一个线程因为等待数据而进入等待状态时,CPU可以去执行另一个线程,其中线程之间的切换只需要极少的时间代价

指令级并行(Instruction-Level Parallelism)

  1. 现代处理器可以同时执行多条指令的属性成为指令集并行,每条指令从开始到结束大概需要20个时钟周期或者更多,但是处理器采用了非常多的技巧可以同时处理多达100条指令,2020年的处理器可以保持每个周期同时执行2~4条指令的执行效率,具体体现是流水线技术

单指令多数据(Single Instruction Multi Data)

  1. 特殊的硬件部件
  2. 功能:允许一条指令执行多个并行的操作
  3. SIMD的指令多是为了提高梳理视频,以及声音这类数据的执行速度,比较新的Inter以及AMD的处理器都是支持SIMD指令加速的

Abstraction in Computer System

四个抽象层次

  1. 文件(File) :对IO设备的抽象
  2. 虚拟内存(Virtual Memory):对IO设备和内存的抽象
  3. 进程(Process):对处理器,内存和IO设备的抽象
  4. 虚拟机(Virtual Machine):对操作系统,处理,内存和IO设备的抽象,即对计算机系统的抽象
  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值