读书笔记:CSAPP_Chapter 1 A tour of computer systems
…
Chapter 1
1.1信息就是位+上下文
信息都是使用btye来存储,但不同的环境下储存的东西可能不一样(如内存中的程序,磁盘文件等等)
什么是ASCII?
ASCII(American Standard Code for Information Interchange):*美国标准信息交换码, 用一个字节的7位可以表示。(所以使用一个字节就可以存下)
除此之外还有很多的字符集如:*ISO8859-1、Unicode(为了统一全球的所有字符-2Byte)、UTF-8(用来解决Unicode无法区分一个符号一个字节还是两个字节的问题)等


1.2程序被其他程序翻译成不同的格式
从hello.c(我们读得懂的文本文件)到hello(机器读得懂的文件)的翻译过程由编译器完成
名词解释
内核:操作系统中用于资源分配和硬件管理的程序称为“内核”
GNU(GNU‘s Not Unix):是一个类Unix操作系统(开源),包含了Unix操作系统的所有主要部件的环境,但内核是Linux,GNU环境里包括了EMACS编译器、GCC编译器等工具。
GCC(GNU Compiler Collection – 编译器套件):是由GNU开发的编程语言译器,支持多种语言(如c、c++、java等)
编译系统(compilation system)
(小括号中的为各个prosseor的名字)

hello.c: 程序员通过编辑器创建并保存的文本文件
预处理器(Pre processor ):根据“#”开头的的命令修改原始的c程序,将其直接插入程序文本得到hello.i
编译器(Complier):将文本文件hello.i翻译为文本文件hello.s,是一个汇编程序,(将不同的编程语言最终使用的都是相同的汇编语言)
汇编器(Assembler):将汇编程序汇编为一个二进制文件hello.s,内部为可重定向的目标程序(指令编码)
链接器(Linker):将printf.o(printf为标志C库的一个函数,printf.o是预编译好了二进制文件)和hello.o通过某种方式合并得到hello(二进制文件),加载到内存中被系统执行。
1.3为什么要了解compilation system
1.优化程序的性能(chapter3、5、6):不同的c语言语句转化为机器代码的方式不同,导致运算的快慢不同。。。通过了解编译系统,写出更加合理快速的code。
2.理解链接时出现的错误(chapter 7)
3.避免安全漏洞(chapter 3)
1.4处理器读取并解释储存在内存中的指令(shell)
shell:命令行解释器(a command-line interpreter)
shell的构成:提示符+待输入的命令行
- 如果待输入的命令行是内置的shell命令,则直接运行
- 如果不是,shell将假设它为一个可执行文件,输入后shell将加载并运行(如hello),然后等待程序终止。
在Unix上运行可执行程序要借助shell
1.4.1系统的硬件组成
1.总线(Buses)
贯穿整个系统的电子管道。(通常传送定长的字节块,也叫字(Word),机器字的长度(字节数)叫字长 如16位 32位 8个字节-64位)
2.I/O设备(I/O Device)
系统与外部世界的联系通道(上图中:作为用户输入的鼠标和键盘,作为用户输出的显示器,以及长期存储数据和程序的磁盘(hello就存放在磁盘中))
IO设备通过控制器或者适配器和I/O总线相连。 作用:I/OBus和I/O设备之间传递信息 区别:控制器集成在主板上,和适配器则是插在主板插槽上的卡
3.主存
主存是一个临时存储设备,在处理器执行程序时,用来存放程序和程序处理的数据(由dynamic random access memory 动态随机存取存储器构成,是一个线性字节数组,每个字节都有唯一的地址)
4.处理器(Processer==central processing unit)
处理器也叫中央处理单元,是解释和执行存储在主存中指令的引擎。
CPU的组成:
4.1程序计数器(program counter - PC):是一个大小为一个字(也就是机器的字长)的存储设备(寄存器),pc是cpu的核心;从上电开始到断电,处理器一直执行pc指向的指令,执行完后再更新pc指向下一条指令。
执行一条指令的步骤:1.处理器将pc指向的内存处读取指令 2.解释指令中的位 3.执行该指令的简单操作 4.更新pc
4.2寄存器文件(register file):是一个小型存储设备,由一些单个字长的寄存器组成
4.3算术/逻辑单元(arithmetic/logic unit - ALU):计算新的数据和地址值
CPU指令:
加载(load):从主存复制一个字节或一个字到register file
存储(Store):从register file复制一个字节或一个字到主存
操作(Operate):把两个寄存器(from register file)的内容复制到ALU,ALU对两个字做算术运算,并将结果存放到一个寄存器(from register file)
跳转(Jump):从指令(from main memory)中抽取一个字到PC中
指令集架构:描述每条指令的效果
微体系结构:描述处理器是如何运行的
1.4.2运行hello程序
Programm from disk to main memory :diret memory access直接存储技术
1.5 高速缓存(Caches Memory)
为什么要有Caches Memory
1.hello的程序从Disk到Main memory再到CPU消耗了大量的系统开销,如何简化流程减小开销?
2.根据越小的存储器运行越快的原理,处理器从Register File读取数据文件的速度»主存»磁盘,如何让处理器拥有大存储容量大同时还有较快的运行速度?
因此为了减小主存和处理器的读取数据速度的差异,在CPU内设置Caches Memory存放经常需要访问的数据。
1.6 存储设备的层次结构
Register File是 L1的高速缓存,L1是L2的高速缓存(以此类推)
1.7操作系统管理硬件
当我们运行hello程序和shell程序时,我们都没有直接访问IO设备和主存,我们使用操作系统提供的服务。
操作系统:应用程序和硬件之间的软件
作用:1.防止硬件被失控的软件滥用 2.向应用程序提供简单的机制来控制复杂的硬件
processes:进程
virtual memory:虚拟内存
Files:文件
1.7.1进程
定义:是对一个正在运行的程序的抽象
并发:多个进程交错执行程序(context switching)
Context:某个进程运行所需要的所有信息(如:PC和寄存器文件的当前值等等)
Context Switch:进行进程切换时,保留当前进程的所有Context,恢复新进程的上下文。
控制权:进程和操作系统都有控制权,操作系统管理分配控制权。(操作系统是房东,房东可以把房子租给租客(进程),也可以收回控制权)
内核:操作系统代码常驻主存的部分,由管理进程的所有代码和数据结构组成。
从一个进程到另一个进程的切换是由操作系统内核(kernel)决定的
1.7.2线程
定义:一个进程可以由多个线程组成,每个线程都在运行进程中的Context,并共享同样的代码和全局数据。
1.7.3虚拟内存
定义:为每个进程都提供一个假想的主存
程序代码和数据:在进程一开始运行时就指定大小
heap:可以动态的收缩和扩展(chapter 9)
共享库:存放C标志库和数学库
stack:实现函数的调用(chapter 3)
内核虚拟内存:不允许读写和直接调用(通过系统调用指令调用–p12页提到了)

每个进程都有自己的虚拟内存(结合下图来理解)
1.7.4文件
文件就是字节序列(包括Disk、I/O设备、显示器等等)
1.8网络通讯
将网络看作一个I/O设备处理。

1.9重要主题
1.9.1Amdahl定律
系统执行某一程序需要时间:Told
在执行这一程序中,有 αTold的时间花在某部分A上
所以执行程序的总时间为:(1- α)Told+ αTold
假设现在A被优化了k倍,执行A需要的时间变为了 αTold/k
所以现在Tnew = (1- α)Told + αTold/k
Told / T new = 1/(1- α+ α/k)
很有意思的事情时 就算k为∞,加速必也还要看1/(1- α)
1.9.2并发和并行
并发(concurrency):同时具有多个活动的系统(让计算机做的更多)
并行(parallelism):用并发使一个系统运行的更快(让计算机做的更快)
1.线程级的并发
传统意义上的并发是模拟出来的,是通过进程之间的快速切换实现的。–单处理器系统
多处理器系统:由单操作系统内核(kernel)来控制多处理器组成的系统。
多核(multi-core):多个CPU核集成在一个电路板上,但仅备份必要的资源(如PC、Register File、Cache),其他的资源(如浮点运算单元unites of floating-point arithmetic)有cpu共享
每个core都有自己的Cache d-cache:保存最近取得的数据 i-cache:保存最近取到的指令(instructions)
超线程(Hyperthreading):也叫做同时多线程(simultaneous multi- threading)
定义:运行一个cpu同时执行多个控制流的技术
常规的处理去需要花很多的时间(2000个时钟周期)来进行线程之间的切换,而Hyperthreading可以在单个时钟周期的基础上决定执行哪一个线程(比如某个线程需要等某些数据被装载到cache中,那就可以去另处理另一个cpu核心),这时的两个线程是同时运行的。
2.指令级并行
定义:同时执行多条指令
将处理器的硬件划分为不同的阶段,且这些阶段可以并行的操作,这些不同的阶段对应了一条指令的不同部分,由此就可以处理不同指令的不同部分(当某条指令的某一部分执行完后,就去执行下一条指令的该部分)
超标量处理器(super scalar processor):处理器可以达到比一个周期一条指令的执行速率更快的速率。(chapter 5)
3.单指令,多数据(single-Instruction, Multiple-Data Parallelism - SIMD):可以对一条指令,多个数据进行操作(比如单精度浮点数指令可以同时处理8对数据)(chapter 5)
1.9.3抽象性
将计算机的硬件抽象为不同的stuff。如下图
操作系统提供了对Processor、Main memory、I/O device的抽象

Part I Programm Structure and Execution
-
Basic date types 整数、实数运算如何在计算机中运算
-
机器级别的指令如何操作这些数据
-
c语言是如何翻译为这些指令的
-
几种实现处理器的方法
-
存储器子系统的设计