深入理解计算机系统读书笔记(第一章 计算机系统漫游)

第一章 计算机系统漫游

本章主要从计算机系统的基本构成,很笼统抽象的讲解了计算机系统的运行原理和基本概念。

1.1 信息就是位+上下文

每一段代码在计算机中存储的时候都是字节序列一个字节等于8位(bit),比如下代码:
Hello.c:

#include <studio.h>

int main()
{
    printf("hello,World\n");
    return 0;
} 

这段代码存储在计算机中时,编码后用字节序列来存储代码信息(每一种编码方式获得的字节序列不尽相同),例如用ASCII码(每一个字节对应一个字符)得到的是如下序列形式:
在这里插入图片描述
比如一个字母i,它在计算机中存储的字节是:105
我们在屏幕上看到的字符,在计算机中存储的都是一字节序列存储起来的,至于字节序列的差异是由编码方式决定的
像这种我们可读的代码文件都称为文本文件,其他的文件都是二进制文件
计算机中存储文件或传输的信息,都是对应的字节序列。区分这些序列区别的就是与这些序列的上下文,一段相同字节序列在不同的上下文中可能有不同的含义,比如它可能表示一个字符、整数、浮点、负数或是机器指令。

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

源代码经过编译系统的处理,就被翻译成为可执行的二级制文件:
在这里插入图片描述

  • 预处理:预处理是执行程序中的预编译指令,还要处理代码中的"#"开头的命令,比如处理头文件,会把相关头文件包含的信息复制到本段代码中来,形成hello.i文件
  • 编译器:编译器(包含一个汇编语言程序)会将hello.i文件翻译成为hello.s。它包含的汇编语言程序为不同高级语言的不同编译器提供了通用的输出语句。
  • 汇编阶段:汇编阶段是将hello.s中的指令打包成为一个可重定位目标程序hello.o,这是二进制文件。
  • 链接阶段:连接器负责将各个部分的调用整合在一起,最终打包成为可执行目标文件。

1.3 了解编译系统如何工作是大有益处的

  • 优化程序性能
  • 理解链接时出现的错误
  • 避免安全漏洞

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

在这里插入图片描述

1.4.1 系统的硬件组成

  • 总线
    总线,负责在各个部件之间传递数据,被设计成为传送定长的字节块,也就是字(word),现在的机器分为32位(字长为4字节),或者64位(字长为8字节)
  • I/O设备
    计算机系统都是通过I/O设备与外界交互。每一个I/O设备都是通过控制器或适配器与I/O总线相连。控制器与适配器是根据集成在计算机上的方式来区分:控制器是直接集成在主板或者I/O设备本身带有的,而适配器是插在主板卡槽上的卡,他们的功能都是在I/O设备和I/O总线之间传递信息
  • 主存
    从物理上来说,主存是由一组**动态随机存取存储器(DRAM)**芯片组成,从逻辑上来说,存储器是一个线性的字节数组,每个字节都有其唯一的地址。一般来说,组成程序的每条机器指令都由不同数量的字节构成。
  • 处理器
    中央处理器,即CPU,简称处理器,处理器的核心是一个大小为一个字(注意是字(32位或64位),不是字节)的存储设备(寄存器)成为程序计数器(PC),从开机开始PC就指向主存中的某条机器指令,并执行该指令,执行完成后,更新PC再继续执行。CPU的操作围绕着主存,寄存器文件(register file)和逻辑/算术单元(ALU)进行。寄存器文件是由单个字长的寄存器组成,每个寄存器都有唯一的名字。CPU可能会有以下操作:
    • 加载: 从主存复制一个字节或字到一个寄存器,覆盖到寄存器中的内容
    • 存储:从寄存器中复制一个字节或字到主存,覆盖主存中的内容
    • 操作:把两个寄存器中的内容复制到ALU,并进行运算,运算结果复制到一个寄存器中
    • 跳转:从指令本身中抽取一个字,复制到PC中, 以覆盖PC中原来值

1.4.2 运行hello程序

当你在shell窗口敲入hello命令时,计算机会将你键盘敲入的信息存入,CPU中的寄存器中,然后再存入主存中:
在这里插入图片描述
当你完成输入时敲下回车,计算机会在磁盘上找到hello程序,并将其存入主存(利用直接存储器技术(DMA)数据可以从磁盘直接到达主存):
在这里插入图片描述
主存会将读取的hello程序的内容存入CPU的寄存器,CPU运算完成后,会将结果输出到显示屏上,整个顺序如下:在这里插入图片描述

1.5 高速缓存至关重要

从上面的例子可以看出,程序的执行过程可以看出,计算机系统花费了大量的时间进行复制操作, 这些操作往往会成为处理器运算的瓶颈,CPU运算能力提升迅速。加快CPU运算速度比加快主存的运算速度要容易和便宜得多,所以针对CPU和主存之间的差距就催生了高速缓存存储器(cache memory.)。
处理器中的高速缓存是分级的,能力越强的CPU可能会拥有2级甚至三级缓存,这使得处理器在获取数据时比直接从主存中获取数据快得多。让经常被访问的数据常驻高速缓存中,就会成倍的提高计算机的运行速度。

1.6 存储设备形成层次结构

在较大较慢的存储器之上加入较小较快的存储器的想法已成为普遍观念:
在这里插入图片描述

图上,存储器层次结构越往上价格越贵,速度越快。程序员可以利用对整个层次结构的理解来提高程序的运行效率。

1.7 操作系统管理硬件

在你执行程序的时候,直接提供服务的是操作系统,它使得计算机硬件有序安全的运行,操作系统有两个基本功能:1.防止硬件被程序滥用;2.向程序提供一致的机制来控制复杂而不同计算机硬件。操作系统通常将计算机硬件抽象成为程序中常用的概念:
文件是对I/O设备的抽象,虚拟内存是对主存和磁盘I/O设备的抽象表示,进程是对I/O设备、处理器和主存的抽象表示。
在这里插入图片描述

1.7.1 进程

进程是操作系统对一个正在运行的程序的抽象。一个进程的运行就像是该程序在独占计算机硬件资源一样,但实际上CPU总是在不同进程之间做切换,由于运行速度太快,我们无法感知而已。操作系统实现这种交错执行的机制成为上下文切换,即保存进程运行的状态和上下文,以便在下次运行该进程时,可以从原来的状态继续执行。

1.7.2 线程

一个进程还可以有多个线程组成,这些线程共享进程的代码和全局数据。多线程比多进程之间更容易共享数据

1.7.3 虚拟内存

每个进程都有自己的虚拟内存,表现就像是这个进程单独使用主存一样。不同的进程看到的虚拟地址空间是一样的:
在这里插入图片描述
虚拟地址空间是从0开始,从最下面的地址一直往上依次增加:
最下面开始依次为:

  • 程序的代码和数据,加载程序时完整,是根据可执行目标文件的内容初始化的。
  • 堆,程序开始时,堆就已经初始化了大小,但是它可以根据程序运行时的状态动态的扩展和收缩(malloc 和 free 函数)
  • 共享库。 地址的中间会存放代码的共享库的代码和数据。
  • 栈。 用户虚拟地址空间顶部是栈,是运行时函数调用会用到的内存空间。当调用一个函数,栈就会增长,函数返回时就会收缩。
  • 内核虚拟内存:地址顶层空间的区域是为内核保留的,不允许用户直接访问和读写这个区域,必须调用内核来执行该区域的操作。

1.7.4 文件

文件就是字节序列而已,所有的I/O设备都可以抽象的看作为文件,系统中可能有各式各样的文件,程序员可以在不懂磁盘读写技术的情况下来使用它们

1.8 系统之间利用网络通信

计算机练上网络后,就相当于I/O多了一个设备,可以从该设备上获取数据,也可以往该设备上传输数据。就好像是本地计算机的一部分了。
在这里插入图片描述

1.9 重要主题

1.9.1 Amdahl定律

本节主要介绍了一个定律Amdahl定律,根据这个定律,我们可以得到一些普遍的指导性的结论: 这定律的主要观点就是,想要显著加速整个程序,必须全面提升程序中相当大部分的速率。

1.9.2 并发和并行

现阶段的处理器会有多核的情况(将多个处理器集成到一个集成电路芯片上),更先进的会有超线程的处理器,超线程的处理器可以在单个周期内决定执行哪一个线程,(比如I7 处理器 每个核可以执行两个线程,让处理器可以在单个周期内决定执行哪个线程,这使得4核的处理器,可以并行地执行8个进程)这使得CPU可以更好的利用计算资源。多核处理器可以并发的执行多个任务,而减少不会出现切换进程的情况。
而在更低的层次上,处理器可以同时执行多条指令的属性称为指令级并行。比如有的处理器就能够达到每个时钟周期2~4条指令的执行速度。如果处理器可以达到比一个周期一条指令更快的执行速率,就可以称之为超标量(superscalar)处理器。
在最低层次上,一条指令可以并行执行的操作,成为单指令、多数据,即SIMD并行,这些SIMD指令多是为了提高处理影像 、声音等资料的处理速度。更可靠的方法是用编译器支持的特殊向量数据类型来写程序,比如GCC就支持向量数据类型。

1.9.3 计算机系统中抽象的重要性

之前的抽象介绍基础上,再加上一个抽象,虚拟机是对计算机的抽象。
在这里插入图片描述

1.10 小结

读起来很多概念很常见,但是在具体的细节和概念,自己理解还是有很多模糊把握不准的地方,毕竟才第一章,也只是概览了一下,读完后面的章节才回头来看看吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章