RISC CPU喜欢把策略决定留给软件负责,而不是交给硬件。RISC的原则倾向于灵活通用的解决安案。这使得MIPS MT有以下几个特点:
1.互相可见线程寄存器:这给了操作系统对多线程的完全控制。mftr和mttr是特权指令允许操作系统软件掌握了解不同TC的寄存器。这是所有跨线程初始化和维护的基础。
2.启动时为单线程:这点遵循了引导软件最少差异的原则。操作系统或者引导软件在准备好后可以唤醒更多线程。
3.同时提供两种形式的多线程:最小开销线程引擎和完全的“虚拟CPU”可以混合匹配。基本的MT特性就是最小线程引擎,称作TC。如果我们就停留在这一步,CPU中除了直接的线程环境外其它所有的东西都是共享的。
其实我们允许MT CPU复制一个Mips32/64兼容的CPU所需要的一切。这些类似CPU的寄存器组合其它资源的每一个叫做VPE:一个或多个TC和VPE相关联,并共享他们的寄存器和资源,VPE中的TC构成一个“虚拟处理单元,”这就是VPE缩写的来历。一个CPU可以实现多个VPE以生成看上去像多个CPU的东西。
MIPS公司第一个MT产品,34-K CPU,最多可以有五个TC在两个VPE之间任意分配。
VPE间可以共享很多东西,当然每个VPE从软件上等价于一个MIPS32 CPU:这不是真的双CPU,只是看上去很像。高速缓存、主流水线、控制逻辑、算术逻辑单元和系统接口都是共享的。TLB在不同VPE间可以用硬件隔开,或者共享。
机器运行的每个指令都有一个TC号,用来选择具体的环境。当该指令访问某些状态的时候——例如读写通用寄存器的时候——就用其TC号来扩展已经定义在指令内的寄存器号域。一条指令根据不同的TC号看到的是一组不同的寄存器集:非常简单但是的确有效。
由于上面提到的TC/VPE技巧,MIPS MT不是那么简单。这条指令可能是TC#5的或者VPE#1.这个应当没问题。当然更为复杂的是,让那些不能简单的归为寄存器的CPU资源工作。但是那已经不属于体系结构,而是属于具体实现了;这些材料你必须阅读CPU手册。
MT规范没有硬件规定,但是实际的MT CPU需要能快速切换线程,否则线程切换损失的时间可能会吃掉潜在的吞吐量增加。其它东西都一样,通常最好在尽可能细的粒度上混合线程:在单发射CPU中,这等于说只要多个线程准备好,每个时钟周期从不同线程各发射一条指令。
一、MT新增的CP0寄存器
这些寄存器可以分为三组:提供给每个TC的、提供给每个VPE的、还有几个是提供给每个CPU的。最后一个是提供CPU的资源清单的寄存器,可以共享;这些不进一步说明。
每个TC的寄存器包括:
1.TCHalt:一位的寄存器,写入1让目标停机。目标TC停机时,其状态是稳定的,可以安全写入它的寄存器。
2.TCRestart: 线程“PC”——当线程停止时,这就是下次运行时第一条指令的地址。当线程不是停止状态时,没有太多的意仪。
3.TCStatus:各TC的“遗留”域——内核/用户状态、ASID、以及指令集选项标志。也有一个标志表明线程停止的指令位于分支延迟槽。
4.TCBind:包含与该TC关联的VPE的ID,以及该TC的ID,后者是只读的。
5.TCContext: 一个纯粹由软件读写的寄存器,典型的用法是存放特定操作系统的线程ID。
各VPE的寄存器VPEControl用于操作系统运行过程中可以合理改变的控制域,而VPEConf0-1的配置域极可能是一次设置后就再也不变了。
二、异常和中断
单线程的MIPS体系结构的CPU的异常通常对流水线式极具破坏性的,常用的实现方法丢弃了许多执行状态。MIPS MT机器上的异常发生在线程环境中——其它的线程可望不受打扰继续运行。所以可以预计当我们在多线程机器上重新定义线程时会有困难。
心中要记住操作系统是一个程序。具体哪个TC执行哪一部分可能关系不大。如每个异常处理程序自身就构成一个线程。所以要运行一个异常处理程序,我们需要借用一个TC来中断其原来的线程并运行这个异常处理线程。
异常分两种类型。中断是异步的——它们的发生原因与具体指令无关。但是大多数其它异常是同步的——它们与特定的指令相联系。我们先看看后一种类型。
同步异常处理程序由导致异常的指令的TC运行。TC立即停止正常线程上的工作,开始从适当的异常处理程序取出指令执行。
MIPS MT ASE规定一旦TC进入异常状态,同一VPE内所有其它TC一律暂停。直到异常处理程序离开异常模式,其他TC的指令才可以执行:就是说,要一直等到SR位被异常处理程序结尾的eret指令清零,或者因异常处理程序分支到操作系统较少受限制的代码部分而清零。异常处理程序尽量减少花费在异常态的时间本来就是良好的做法,大多数操作系统都是这样做的。
但是如果你的应用程序需要最大化并发性,你应当考虑最小化异常——你可以用一个在ITC访问或者yield条件上阻塞的线程。当然安排异常处理程序保存必要状态以便推出异常模式。
三、MIPS MT和中断
在MIPS体系结构中,中断管理通过CP0寄存器进行。这些寄存器为每个VPE而不是每个TC复制一份,所以中断屏蔽和传递由每个VPE管理。甚至硬布线连到核的中断信号也是由每个VPE处理。
每个中断输入可能只连到一个VPE上,也可能连到全部VPE上,所以哪个VPE接收中断涉及到系统的硬件布线方式,但也可能和软件配置有关。如果你不加屏蔽地把一个中断连接到多个VPE上,任意几个VPE都可能响应中断异常——你大概不希望发生这种情况,所以要么别连线要么别使某些中断。
中断异常可以由于VPE相联的任何可用的TC响应。
MIPS体系结构已经提供了多种方式来拒绝中断异常。异常模式、全部中断使能标志和单个终端的屏蔽位,即SR(EXL)、SR(IE)、SR(IM)位——这里列出的不是全部——都可以防止该VPE上的线程发生中断。
MIPS MT规范增加了又一个不响应中断的理由。现在你可以设置一个新的每个TC的CP0寄存器域,该域可以防止特定TC被用于中断异常。
四、线程优先级提示
有些应用程序开发人员对于可以控制CPU带宽偏向一个线程而不是另一个线程的能力表示感兴趣。MIPS MT规范提供了这个特性,尽管并没有说明怎样实现。一个调度策略管理器是CPU外部的一块逻辑,可以针对具体应用定制。PM为每个TC生成一个2位的优先级。早核里面,总是优先执行可运行的高优先级TC,而不是可运行的低优先级TC。
五、用户权限的动态线程创建——fork指令
多线程硬件还有一个很有意思但还没有商用化探索的应用,就是提供另外一种发现及利用串行算法的并行性的方法。例如:一个循环可以通过两个线程分别运行其奇数和偶数次循环来优化。
如果这要在带保护的操作系统的支持下完成,就要求有一个非常高效的机制即需发射新程。MIPS MT的fork指令提供了这样一种机制。
这样fork d,s,t成了一条用户级指令。如果一切正常。该指令在准备就绪的TC上开始一个新线程,从s所指向的指令处开始执行。子线程的d获得父亲线程的t值。
操作系统通过维护一个分支就绪到那时此外空闲的TC缓冲池通过一个标志位来识别。当新线程完成应用程序的任务后,就终止执行,并用一条yield#0指令把TC交还给缓冲池。
转自与非网