第1章——引言;第2章——指令系统;第3章——特权指令系统;第4章——软硬件协同。
第1章 引言
1.1 计算机体系结构的研究内容
- 按下键盘到幻灯片翻页:键盘传信号到南桥,南桥保存键盘编号并发出外部中断,中断信号附在指令上进入ROB,当执行到该条指令时清空流水线,然后设置系统状态为核心态(RISCV就是修改sstatus)、保存异常时PC值(RISCV就是sepc)、例外原因(RISCV就是scause)。然后置PC为中断服务程序入口,跳转过去。跳转之后保存上下文,向CPU读例外原因(中断),然后向南桥读中断原因(敲空格键),之后找到一个PowerPoint进程正处于阻塞态,等待空格键,于是唤醒这个进程。随后PowerPoint准备下一张幻灯片内容,再给一个中断,把待显示内容传给显存,并让GPU刷新屏幕。
- 如果翻页过程中卡顿,可能是什么原因?
- 打开进程过多。
- CPU主频低(可能性较小,因为翻页并不需要太高的性能)。
- 矢量图较多,GPU性能低。
- 要显示的数据量比较大,内存带宽不足。
- 通用计算机系统的结构层次:
-------------------------- | 应用程序 | -------------------------- API -------------------------- | 操作系统 | -------------------------- ISA -------------------------- | 硬件系统 | -------------------------- 工艺模型 -------------------------- | 晶体管 | --------------------------
- 冯诺依曼结构:
- 构成:控制器、运算器、存储器、输入设备、输出设备。
- 指令和数据存储在存储器中,CPU从内存中取出指令和数据进行运算,并把运算结果存在内存中。
- 本质特征:存储程序和指令驱动执行
1.2 衡量计算机的指标
性能、价格和功耗是衡量一台计算机好坏的三个重要指标。
1.2.1 性能
影响性能的因素:
- 指令数:算法、编译器、指令系统设计
- CPI:指令系统设计、微结构
- 每周期用时(主频):微结构、电路设计和工艺
1.2.2 价格
- 性价比:
- 高性能计算机:首要考虑性能
- 嵌入式应用:为追求低功耗低成本,可以牺牲一部分性能
- 介于二者之间:性价比
- 影响成本的因素:芯片成本为主,含一次性成本(研发成本)和制造成本(生产量上来了,生产技艺就会改良,次品率少了,成本也会下降)。
1.2.3 功耗
- 动态功耗
- 开关功耗:电压变换(0/1),电容充放电
- 短路功耗:电压翻转过程中,N管和P管暂时性同时打开,产生短暂的短路
- 静态功耗
- 漏电功耗:源极、栅极、漏极、衬底之间都有可能发生漏电,产生漏电功耗
降低电容、电压,降低频率,改进工艺;结构和逻辑设计上降低翻转率等。
1.3 计算机体系结构的发展
- 计算机体系结构发展的动力:
- 工艺技术的发展:半导体工艺技术和计算机体系结构技术互为动力;摩尔定律在逐渐失效,工艺技术对体系结构的影响在降低。
- 应用需求的提高:网络计算、游戏等;将成为首要动力。
- 摩尔定律:
- 常规表述:晶体管数目每18-24个月翻一番。
- 不是客观规律,是主观经验。
- 摩尔电路与计算机结构进步:
- 第一代:电子管计算机
- 第二代:晶体管计算机
- 第三代:中小规模IC计算机
- 第四代:大规模IC计算机
- “墙”:
- 存储墙:CPU和存储器速度的剪刀差
- 功耗墙:高主频设计带来过高的功耗
- 成本墙:越来越贵
- 复杂度墙:芯片设计复杂度越来越高,难以设计
- …
1.4 体系结构设计的基本原则
平衡性、局部性、并行性、虚拟化。
- 平衡性:统筹兼顾。木桶原理,各结构应平衡设计,避免某个结构性能过低制约整个系统。例如CPU的计算性能和访存带宽的平衡;Amdahl定律。
- 局部性:重点突出。利用局部性进行系统性能优化;RISC的二八定律;访存局部性(时间、空间)产生Cache、TLB、预取等结构和设计。
- 并行性:开发各个层次的并行性。
- 虚拟化:“用起来是这样,实际上是那样”。比如虚拟内存、多线程、虚拟机、Cache的提出、Cache一致性协议等。
第2章 指令系统
2.1 指令系统简介
是软硬件的界面,不仅与指令功能有关,还涉及到运行环境(Cache管理、存储管理、安全管理、异常和中断处理……)。
2.2 指令系统设计原则
- 指令系统设计的基本原则:
- 兼容性:关键特性,对软件向前兼容,支持过时指令。
- 通用性:各种应用的需求,例如视频解码相关指令等。
- 高效性:便于CPU硬件结构的设计优化,提升性能。
- 安全性:考虑不同的安全要求,提供保护等。
- 指令系统设计的影响因素:
- 工艺技术:片内可集成晶体管数目增多,功能集成度提高,可支持更多功能。
- 计算机体系结构:直接影响;指令系统兼容性与体系结构发展之间的矛盾。
- 操作系统:异常和中断、安全等级、多进程和虚拟内存的支持等(例如专用控制寄存器操作)。
- 编译技术:使编译器有效地调度指令,增加编译灵活性等。
- 应用程序:算法支持、应用需求。
2.3 指令系统发展历程
2.3.1 指令内容的演变
- 根据指令长度的不同,可分为CISC(复杂指令系统)、RISC(精简指令系统)和VLIW(超长指令字)。
- CISC变长;RISC定长;VLIW本质上是多条同时执行的指令的组合。
2.3.2 存储管理的演变
- 段式、页式、段页式。
- 三种存储管理方式的地址转换过程。
2.3.3 运行级别的演变
无管理->增加保护模式(权限)->增加调试模式->增加客户模式(又称虚拟化支持)
不同运行级别下可访问的资源不同,一般是包含关系。
2.4 指令系统的组成
操作码和操作数。
2.4.1 地址空间
- 处理器可访问的地址空间包括立即数、寄存器空间和系统内存空间。
- 寄存器空间:通用寄存器、专用寄存器、控制状态寄存器;
- 系统内存空间:内存空间、IO空间。
- 使用相同的load/store指令访问内存空间和IO空间。
- 处理器对IO空间的访问不能经过Cache,因此需要有标记,指明访存是否经过Cache。
- 根据指令使用数据的方式,指令系统可分为堆栈型、累加器型、寄存器-存储器型、寄存器-寄存器型。
- 堆栈型:操作数都在栈顶,运算结果默认存回栈顶,通过PUSH和POP改变栈的内容。
- 累加器型:一个操作数隐含在累加器中,另一个操作数由指令指定,可以是内存中的值,也可以是寄存器中的值。
- 寄存器-存储器型:跟累加器型比较像,但是没有隐含操作数,操作数为寄存器和内存单元,须显式指定。
- 寄存器-寄存器型:除了访存指令之外,其他指令只能操作寄存器。
- 早期多用堆栈型和累加器型,主要目的是降低硬件实现的复杂度;现在多用寄存器-寄存器型,目的在于提高访存速度以及充分利用局部性原理。另外,寄存器-寄存器型的优势是容易判断相关。
2.4.2 操作数
- 大尾端和小尾端:小尾端起始地址在一个字的最后一个字节,大尾端反之。
- 寻址方式:寄存器寻址、立即数寻址、偏移量寻址、寄存器间接寻址等。
2.4.3 指令操作和编码
- 从功能上看,可分为四大类:运算指令、访存指令、转移指令、特殊指令。
- 运算指令:加减乘除、移位运算、逻辑运算等;
- 访存指令:load/store,取数长度、寻址方式等;
- 转移指令:相对/绝对、直接/间接、条件/无条件;
- 特殊指令:TLB管理、Cache管理、异常管理、安全管理等。
- 最常用的指令是一些简单指令,把这些加快可有效提升性能,其它的慢一点没关系(局部性原理)。“常用的做得快,少用的只要对。”
- 转移指令确定转移条件的方式:判断条件码和比较寄存器的值。
- 判断条件码:采用运算指令计算条件,置条件码,条件指令使用条件码判断是否转移。
- 比较寄存器的值:转移指令直接比较寄存器判断是否转移。
2.5 RISC指令集比较
比较的RISC指令集:MIPS、PA-RISC、PowerPC、SPARC v9、LoongArch。
RISCV也是常用的RISC指令集。
- 指令格式:主要组成元素基本相同,只是摆放位置存在差别。
- 寻址方式:都支持四种基本的寻址方式——寄存器寻址、立即数寻址、偏移量寻址、变址寻址。PA-RISC和PowerPC支持的寻址方式更多一些。
- 指令功能:区别较大。
2.5.1 不同指令的特色
- MIPS:非对齐访存。LWL读取访存地址所在的字并将访存地址到该字中最低位的字节拼接到目标寄存器的高位;LWR读取访存地址所在的字并将访存地址到该字中最高位的字节拼接到目标寄存器的低位。依尾端而不同:
- SPARC:寄存器窗口。
- PowerPC:Link和Count寄存器。
- PA-RISC:Nullification。
2.6 C语言的机器表示
- 过程调用(函数调用):bl和jr指令。用栈或寄存器保存参数,保存和恢复现场。
- 哪些情况下需要保留和恢复现场?
- 函数调用:sp和ra寄存器需要保存,简单的调用不需要保存。
- 线程切换:几乎全部通用寄存器(除了部分操作系统专用的)。
- 进程切换:几乎全部通用寄存器(除了部分操作系统专用的),其它现场。
- 例外处理:例外处理要用的寄存器要保留。
- 虚拟机切换:所有通用寄存器,部分控制操作系统用的寄存器。
第3章 特权指令系统
3.1 特权指令系统简介
- 用户程序能看到的:用户态指令系统结构、操作系统提供的系统调用(合称ABI)。
- 操作系统能看到的:用户态指令系统结构、特权态指令系统结构。
- 编译器编译不出特权态指令,其为操作系统专用。
- 特权态指令作用:
- 定义和切换运行模式
- 异常与中断处理
- 虚拟存储管理
- 用户态可见的寄存器:
- 通用寄存器(含浮点寄存器)
- 部分控制状态寄存器(如X86的EFLAG,LoongArch的FCSR)
3.2 异常与中断
3.2.1 异常分类
- 异常定义:使软件从正常执行流中脱离的事件。
- 分类:根据来源,分为外部事件、指令执行中的错误、数据完整性问题、地址转换异常、系统调用和陷入、需要软件修正的运算。
- 外部事件:来自CPU流水线外部的事件,也称中断。例如键盘输入。
- 指令执行中的错误:指令未定义、用户态无权访问的指令或地址、除零异常、地址不对齐、整数运算溢出等。
- 数据完整性问题:ECC(检二纠一)或奇偶校验错误,来源于存储器软错误。
- 地址转换异常:虚实地址转换时,没有有效的TLB项。
- 系统调用和陷入
- 需要软件修正的运算:通常来源于浮点运算指令,硬件实现过于复杂而不支持,交给软件。
3.2.2 异常处理
- 精确异常:发生异常时,被异常打断的指令前的所有指令都已经执行完,该指令之后的所有指令都像没执行一样。
- 异常处理流程:异常处理准备、确定异常来源、保存执行状态、执行异常处理、恢复执行状态并返回。
- 异常处理准备:① 记录EPTR,LoongArch将EPTR存储到CSR.ERA寄存器(RISCV:sepc寄存器);② 调整权限等级,LoongArch将CSR.PLV置0以进入最高权限等级;③ 屏蔽所有中断,LoongArch将CSR.CRMD的IE域置0。④ 保存异常发生现场的部分信息,例如将CSR.CRMD的PLV和IE域记录到CSR.PRMD的PPLV和LIE域中,供异常返回时使用。
- 确定异常来源:主要有两种方式:① 发生异常时进入同一个异常处理程序,然后查询异常编号,进入相应的处理函数入口;② 发生异常时根据异常来源进入不同的异常处理程序,这样就自动知晓异常来源。
- 保存执行状态:将通用寄存器和部分CSR压栈。
- 处理异常
- 恢复执行状态:从栈中取出通用寄存器和部分CSR。
- 异常处理返回:同时完成权限等级的切换和返回地址恢复。LoongArch中是ertn指令,x86是iret指令。
- 异常嵌套:将异常分为多个优先级,更高优先级的异常可以抢占处理。
3.2.3 中断
- 有两类异常非常容易出现,地址转换异常(访问地址不在TLB中)和中断(外部事件想要获得CPU)。
- 中断传递机制:从中断源传递到CPU的方式,主要有中断线和消息中断。
- 中断线:中断源不多时,直接从中断源连线到处理器引脚(LoongArch,电平中断);也可以先把连线汇总到中断控制器(这时采用边沿中断),然后转发汇总到(可能是不同的)CPU。但是这样会占用CPU引脚,因此一般只在SoC上使用。
- 消息中断:消息中断以数据(消息) 的方式在系统总线上传递。发中断就是向指定的地址写一个指定的数。
- 向量化中断:嵌入式CPU对中断处理实时性要求较高,因此为每个中断设置独立的入口,进入后直接处理。这样就省去了进入中断处理程序后识别中断源的开销,加速处理。
- 中断使能控制位的原子修改:修改CSR.CRMD中断使能位时,操作必须是原子的,不然也可能被中断打断。方式有:禁用中断、添加专门的位原子修改指令、不允许中断处理程序修改SR、使用通用的方法保证程序段的原子性等。LoongArch中添加了csrxchg指令,专门用来原子地修改中断使能位。
3.3 存储管理
ipad
第4章 软硬件协同
4.1 ABI
- ABI定义了应用程序二进制代码中相关数据结构和函数模块的格式及其访问方式,使得不同的二进制模块之间的交互成为可能。
- 内容:
- 数据表示和对齐要求
- 寄存器使用约定
- 函数调用约定
- 栈布局
- 目标文件和可执行文件格式
- 函数调用规范
- 进程虚拟地址空间布局
- 栈帧布局
4.2 六种常见的上下文切换场景
- 函数调用
- 异常和中断
- 系统调用
- 进程切换
- 线程切换
- 虚拟机:虚拟机无法独立处理内部的上下文切换时,会退出虚拟机的状态,借助宿主机的虚拟化管理软件来完成任务。虚拟机和宿主机之间的切换需要保存和恢复所有可能被修改的虚拟机相关状态信息。
4.3 同步机制
- 自旋锁(自旋等待)、互斥锁(阻塞与唤醒)
- 读-改-写指令、LL/SC指令
- 事务内存:非阻塞的同步机制,核心思想是通过尝试性地执行事务代码,在程序执行过程中动态检测事务间的冲突,并根据冲突检测结果提交或取消事务。