5.2 中断与异常:流水线里的精确打断


5.2 中断与异常:流水线里的精确打断

本节摘要:系统事件分两类——同步的异常(指令自己惹的祸)与异步的中断(外面来的电话),两类都要把处理器精确地送到处理程序入口,且事后能无缝续跑。本节追踪一次陷入从事件到返回的完整旅程,讲清"精确"二字在流水线里的实现——哪条指令背锅、前后的指令怎么办,以及中断延迟的构成与压缩手段。

行话「陷入」到底是什么

体系结构行话里,"陷入"指从当前执行流切换到处理程序的那次硬件跳转——它不是普通跳转指令,而是事件驱动的、带自动记账的切换。异常是同步陷入:非法指令、缺页、访问越权,锅在程序自己的某条指令上,陷入位置精确指向这条指令。中断是异步陷入:外设请求、定时器到点,与当前指令无关,处理器选一个"方便的时刻"打断。两类事件共用同一套档案袋与切换机构,但"精确性"的要求细节不同——这正是本节的主线。

一次陷入的完整旅程

旅程里有三个角色分工值得背下来:硬件自动做原子记账(原因、位置、旧状态一拍写好,不给人插手的机会);软件处理程序做现场搬运(通用寄存器是软件的资产,保存恢复是软件的职责——硬件若也代劳,每次陷入都付全套搬运成本,哪怕事件根本不需要);返回指令做身份恢复。这套分工是"最小自动化"哲学的又一次落地。

「精确」二字的流水线实现

什么叫精确异常?任何一条指令的异常发生时,它之前的指令全部完成、它之后的所有指令仿佛从未执行。语义干净得像单周期处理器。但流水线里同时有数条指令在场,异常可能在不同站被发现——非法指令在译码站、缺页在访存站、后续异常还没轮到它出场——怎么保证"仿佛从未发生"?

实现策略:每条指令在流水线里携带自己的异常标记,一路带到提交点才统一裁决。乱序引擎里就是重排序缓冲:指令可以乱序执行,但异常只在它成为最老指令、即将提交时才被采纳;采纳瞬间,它身后所有指令(无论执行到哪)整体作废,档案袋记下它的地址。顺序流水线同理:异常标记随指令推进,写回前统一仲裁,最老异常优先处理。

这个设计把"精确性"的成本转嫁给提交机制——第三章按序提交在这里兑现了第二重价值。反过来说,任何削弱按序提交的优化(比如提前释放、跳跃提交)都必须重新回答精确异常怎么保,这是高性能设计的红线之一。3.3 讲投机执行时提过"副作用押后提交",与这里是同一条红线在两个场景的投影。

中断的"精确"稍有不同:它不属于任何指令,处理器选在指令边界上响应——通常是提交点之间的空隙。中断因此可以做到"零污染"打断:不需要作废任何已执行指令,只是从下一条指令边界切入。

中断延迟:实时系统的硬指标

从外部事件发生到处理程序第一条指令执行,中间的耗时叫中断延迟。它的构成值得逐项盘点:信号传播(事件源到处理器的路径)、等待指令边界(在飞的指令要提交完,乱序窗口越深这部分越可观)、自动记账与跳转(几拍)、软件现场保存(几十拍的量级,取决于保存多少寄存器)。实时系统关心的是最坏情况的延迟上限——深度流水的乱序核在这里天然吃亏,这也是实时场景偏爱较简单核的微架构理由之一。

压缩手段按层排布:硬件层提供向量化的入口(不同中断源直接跳不同入口,省一层软件分发);软件层用上下文分级保存(先保存少量寄存器快进快出,确实需要再保存全套);系统层给关键中断开专门通道与优先级。第三章到本章的所有设计选择,在"中断延迟"这个指标上一起结账。

中断控制器:事件的分发总机

核外的中断源成百上千,谁负责排队与转发?平台级的中断控制器承担这个角色:每个输入源可配置优先级与使能,电平或边沿触发;当多个源同时申请,控制器仲裁出最高优先级者,汇总成一根线通知处理器;处理器响应后读控制器的领取寄存器领走中断编号,处理完成写回完成寄存器,控制器才放出下一个。这套"领取—完成"握手保证了中断不会丢也不会重复服务。核内的计时器与软件中断则走另一条本地通路,不经外部控制器——时钟中断(7.2 操作系统的心跳)就是从这条本地通路进来的。

嵌套与优先级是调度敏感场景的进阶需求:高优先级中断希望能打断低优先级的处理进行服务。实现上,处理程序入口软件先保存现场、再开全局中断使能,高优先级事件即可嵌套进入——硬件提供了机制(使能位随时可操作),嵌套策略完全由软件决定,又是"最小自动化"的一处体现。

异常的委托转发。不是所有异常都该机器模式处理:监督模式跑着操作系统时,用户态的缺页交给内核处理更顺(它管着页表)。委托机制允许机器模式把特定类别的陷入直接转发给监督模式的入口,减少一次"机器模式收到—转交—返回"的往返。配置合理时,绝大多数陷入走直达通道,机器模式固件只在最底层的少数事件出场——7.2 的启动链条里,委托配置是固件移交控制权前的标准动作。

常见问题快答

问:异常和中断会同时到,谁先处理? 规范的裁决规则是:同步异常属于某条指令,优先随那条指令在提交点处理;中断属于指令边界,排在当前指令之后。两者不会"同时"——它们挂在执行流的不同位置上,硬件按位置裁决。

问:处理程序里再出异常怎么办? 一样走陷入流程,档案袋被覆盖前由软件先把旧值保存——这就是处理程序入口必须谨慎保存现场的原因之一。层层嵌套的异常是内核最考验严谨性的代码段,出错的典型症状是"偶发的、随机的"系统崩溃。

⚠️ 常见坑:中断处理程序里忘了保存处理程序自己会用的寄存器,或返回指令用错了级别的档案袋。前者导致被中断的程序随机坏数据,后者导致身份恢复错乱直接跑飞——两类都是"偶尔才发作"的疑难杂症,规避靠代码规范与静态检查,不靠测试碰运气。

本节要点回顾

  • 两类事件一套机构:异常同步背锅、中断异步选点,共用档案袋与切换流程;
  • 三方分工:硬件原子记账、软件搬运现场、返回指令恢复身份;
  • 精确异常靠提交点裁决:异常标记随指令推进,成为最老指令才采纳,身后整体作废;
  • 中断在指令边界切入:零污染打断,但深度流水加长延迟;
  • 中断延迟是所有微架构选择的合账:实时场景的核选型要在开拍前算清。

身份与事件都有了,最后一节补上内存的门禁表——物理内存保护。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U