计算机组成原理学习笔记

基础知识

冯诺伊曼体系结构

在冯诺伊曼体系结构中,一台计算机的基本组成分为一下5个部分:

  1. 运算器+控制器。即CPU
  2. 存储器
  3. 输入和输出设备

计算机性能

用于衡量计算的性能的两个指标:

  1. CPU执行时间:一个计算请求从开始到结束的CPU耗时
  2. 吞吐量:一段时间内能够处理多少计算请求

CPU执行时间=指令数*指令平均时钟周期数*时钟周期时间

优化CPU执行时间的策略:提升计算机主频(减小时钟周期时间)、优化 CPU 设计使得在单个时钟周期内能够执行更多指令(减小指令平均时钟周期数),以及优化程序代码来减少需要的指令数。

CPU计算的本质:CPU是一种超大规模集成电路,计算的本质就是这些大规模电路不停地进行预设的“开”、“关”动作。

逻辑的处理器数量=物理CPU数 * 核心数 * 每个核心的线程数

指令和运算

if-else 和 switch-case的比较: 通过对两者进行编译之后观察其汇编代码,发现if-else执行时需要将条件一个个的比对,直到找到符合条件的分支。而switch-case则只需要一次的比较就能找到对应的分支,原因是switch-case生成了跳转表,可以通过跳转表的索引直接定位到分支。

函数调用栈:用于在执行函数调用时保存返回后的将要执行的指令地址、函数中的局部变量的栈结构。当出现无限的函数调用或者入栈的变量占用过多的栈空间时,会出现stack overflow错误。

ELF文件:全称是Execuatable and Linkable File,是Linux系统下的一种文件格式。C语言的程序源代码在汇编阶段和链接阶段都会产生ELF文件。运行一个可执行的程序时,装载器会读取这种格式的文件,并把各Segment的内容放到内存中对应的位置,再由CPU去执行。

C语言程序代码通过编译器、汇编器进行编译和汇编,产生ELF格式的文件,此时的文件还不能够被执行,需要通过链接器将多个ELF文件进行链接。链接器要做的工作就是分析各个ELF文件的重定向表、符号表,并将符号引用替换为最终的函数地址,从而完成多个ELF文件的“汇聚”工作,最后产生一个可执行的ELF文件。

二进制编码:在计算机里面,所有的信息、数据都是以二进制进行计算和存储的。比如在对数据进行计算的时候,使用的的是数值对应的二进制计算法方式,在进行数据存储时,写到存储介质的数据也是二进制数据。

字符乱码的原因:当文本内容出现显示乱码时,原因是因为字符内容的编码方式方式和解码方式不统一。比如对“你好”这个文本内容使用了UTF-8编码,但是解码的时候使用GB2312解码,就会导致解码方式和编码方式不统一,从而造成乱码。

浮点数的表示:IEEE 754标准中,32位浮点数由三部分组成:1位符号位(s)表示正负、8位指数位(e)、23位位有效位(f)。有效位和指数位共同决定了浮点数的大小和精度。

由于有的浮点数在转化为二进制时,有效位部分出现循环,导致必须截断丢弃,因此有的浮点数在IEEE 754标准下是无法精确表示和计算的。比如浮点数0.3,转化为二进制小数为0.01001100110011...,“0011”部分会无限循环。

处理器

指令周期:取指、译码、执行。

组成CPU的基本电路:ALU、寄存器电路、PC(指令地址寄存器)、译码器。

CPU的计算流程

指令流水线技术:指令流水线技术是指,在CPU执行指令时,整个执行过程拆分为多个阶段,比如分成三个阶段:取指令、译码、执行,然后让CPU中不同的模块同时进行各个阶段的处理,当一条指令处于译码阶段的时候,后面的指令可以开始取指令阶段,这中设计方式大大提高了CPU的使用率。

冒险:使用流水线技术的CPU需要解决三种冒险,分别是数据冒险结构冒险控制冒险

结构冒险指的是CPU在执行不同指令的不同阶段时,可能需要同一个硬件电路,因而对应的解决办法就是增加对应的硬件支持。

数据冒险指的是不同的指令在对同一个寄存器或者内存地址进行读写时,出现数据依赖问题,可以使用操作数转发+插入NOP等待的机制避免数据依赖(就是通过在硬件层面制造一条旁路,让一条指令的计算结果,可以直接传输给下一条指令,而不再需要“指令 1 写回寄存器,指令 2 再读取寄存器“这样多此一举的操作)。

控制冒险指的是在指令执行过程中,遇到了跳转指令,这时后续的指令就不能按顺序执行了,需要使用跳级后的指令。解决控制冒险的方式:分支预测。最简单的分支预测就是假定不发生跳转,那么后续值的指令顺序取指。如果预测错误需要丢弃正在执行的一些指令。

指令乱序执行:乱序执行技术是指,CPU通过分析指令之间的依赖关系,调整指令的执行顺序,尽可能利用各个计算电路而不是插入NOP这样的空操作。CPU通过指令乱序执行技术,更大化的提高CPU的使用率。

关于多层嵌套for循环写法:高效的写法应该是在保证逻辑正确的前提下,从外层到内层循环次数逐渐增加,这种方式能够更好的利用分支预测

超线程技术:超线程技术是CPU在硬件层面,通过额外增加一份PC寄存器、指令寄存器等硬件,提供“同时”运行两个线程的能力。实际上超线程技术并没有将所有计算电路都复制一份,因此同一个核心在同一时刻并不能运行两个线程,而是在一个线程的指令发生等待时,运行另一个线程的指令,这样看起来就有同时运行两个线程的能力。在并发IO的应用场景下,超线程带来的效益会更加显著。

GPU:图形处理器,用于处理3D图形渲染中需要的计算。早期的GPU没有可编程的能力,只能处理固定的指令。随着技术的发展,现在GPU已经是可编程的了,并且擅长于做大量的数值计算,因此非常适合于深度学习的模型训练。

FPGA:FPGA本质上是一个可以通过编程来控制硬件电路的芯片。通过对FPGA芯片编程,可以将其设计成具有特定功能的芯片或者是CPU这样具有复杂功能的芯片。

ASIC:Application-Specific Integrated Circuit,专用集成电路。是更为专用的芯片,常见的比如有录音笔、摄像头的设备的芯片。ASIC的特点是电路简单、功耗低。

存储与IO系统

存储器体系

一台计算机的工作除了数据计算之外,最重要的就是数据存储。寄存器、高速缓存、主存、硬盘构成现代计算机的存储体系。

CPU操作寄存器的数据,而寄存器中的数据来自于高速缓存,高速缓存的数据来自主存,主存中的数据来自于硬盘,这就是现代计算机的数据访问机制。

MESI协议

现代计算机通常具有多个处理器,即具有多个物理核心。每个核心有自己的多级缓存(cache1、cache2),然后多个核心共享cache3和主存。当不同核心对同一个地址的数据进行访问时,需要保证缓存一致性。

MESI协议是基于总线嗅探写失效机制来保证缓存的一致性。

总线嗅探可通俗的理解为监听总线上的操作信号,这些操作信号可能是某个核心要读取某个地址的数据,或者是某个核心要写某个地址的数据源。

写失效机制是指,CPU核心在更新其缓存中的数据之前,在总线上向其他CPU核心广播缓存中某个地址的数据已经失效了。

TLB

TLB,地址变换高速缓冲(Translation-Lookaside Buffer)。用于提高内存虚拟地址翻译成物理地址的效率。原理如同CPU高速缓存。TLB会把翻译过的虚拟地址-物理地址映射缓存起来,再次收到对同一个虚拟地址的翻译请求时直接可以得到物理地址,而不用多次访问内存中的页表。

IO设备

常见的鼠标、键盘、U盘、显示器等设备都属于IO设备。IO设备要和CPU打交道,需要连接到主板的各种接口(物理上就是各种插槽)。主板的接口上有专属这种IO设备的寄存器以及控制电路。CPU不直接对IO设备进行读写,而是读写IO设备映射内存的地址。

进程IO耗时定位:

  1. 运行top命令,观察%CPU一行的wa数据,wa代表了IO-waite占用CPU的时间,如果这个值比较大,说明很多时间浪费在等待IO上。
  2. 运行iostat命令,查看详细的硬盘的读写情况,kB_read/s 和 kB_wrtn/s 指标,对应着数据传输率的指标。
  3. 使用iotop命令进程的io

IOPS:每秒读写次数,是衡量硬盘读写性能的指标。机械硬盘的IOPS通常在100左右,固态硬盘的IOPS在20000左右

原理应用

AreoSpike数据库:AreoSpike数据库充分利用了SSD硬盘的优势,是一款读写性能优秀的KV数据库。

  1. 在写入数据的时候,AeroSpike 尽可能去写一个较大的数据块,而不是频繁地去写很多小的数据块。这样,硬盘就不太容易频繁出现磁盘碎片。并且,一次性写入一个大的数据块,也更容易利用好顺序写入的性能优势。AeroSpike 写入的一个数据块,是 128KB,远比一个页的 4KB 要大得多。
  2. 持续地进行磁盘碎片整理。AeroSpike 用了所谓的高水位(High Watermark)算法。其实这个算法很简单,就是一旦一个物理块里面的数据碎片超过 50%,就把这个物理块搬运压缩,然后进行数据擦除,确保磁盘始终有足够的空间可以写入。
  3. AeroSpike 给出的最佳实践中,为了保障数据库的性能,建议你只用到 SSD 硬盘标定容量的一半。也就是说,我们人为地给 SSD 硬盘预留了 50% 的预留空间,以确保 SSD 硬盘的写放大效应尽可能小,不会影响数据库的访问性能。

Kafka:利用了内存映射文件机制,避免了数据在内存的多次拷贝,加快了数据处理的速度。在Java中,FileChannel实现了内存映射文件机制,提供了将文件描述符转化为Socket描述符的API,于是将磁盘上的文件读到内存再通过Socket发送到网络上只需要两次数据转移操作:第一次是将文件读到内存,第二次是将内存数据拷贝到网卡数据缓冲区。

posted @ 2021-01-02 11:14  陈玉林  阅读(649)  评论(0编辑  收藏  举报