华南理工大学计算机组成原理2013年大题部分

硬连线控制和微程序控制

问题:硬连线控制和微程序控制的优点和缺点分别是什么?

  • 答案
    • 硬连线控制
      • 优点
        • 速度快:由于控制单元的逻辑是通过硬件电路直接实现的,没有额外的指令解释过程,所以指令执行速度非常快。例如,在一些对速度要求极高的专用处理器或者简单的处理器架构中,硬连线控制可以使指令在一个或几个时钟周期内快速完成,减少了指令执行的延迟。
        • 硬件实现简单(对于简单指令集):如果指令集比较简单,指令的执行步骤相对固定,那么通过硬连线方式构建控制单元的硬件电路逻辑不会过于复杂。这种简单的电路结构能够高效地完成指令的控制功能,并且硬件成本相对较低,可靠性高。
      • 缺点
        • 灵活性差:一旦硬件电路设计完成,修改指令集或者改变指令的执行方式就非常困难。因为控制逻辑是通过固定的电路连接实现的,任何改变都可能需要重新设计和制造硬件电路。例如,如果要增加新的指令或者改变现有指令的操作码含义,几乎需要对整个控制单元进行重新布线和设计。
        • 设计复杂(对于复杂指令集):对于具有复杂指令集的处理器,指令的执行可能涉及多种不同的操作步骤、多种寻址方式以及复杂的操作数组合等。在这种情况下,硬连线控制单元的设计会变得极为复杂,需要大量的逻辑门和复杂的电路连接来实现各种指令的控制逻辑,导致设计周期长、容易出错,并且后期维护困难。
    • 微程序控制
      • 优点
        • 灵活性高:微程序控制的核心是微程序,它是存储在控制存储器中的一组微指令序列。如果需要改变指令集或者修改指令的执行方式,只需要修改微程序即可。例如,当需要增加新的指令时,可以编写新的微程序段来实现该指令的功能,而不需要对硬件电路进行大规模的改动。这种灵活性使得处理器在面对不断变化的应用需求和指令集扩展需求时能够更容易地进行调整。
        • 易于实现复杂指令集:对于复杂的指令,可以通过编写一系列微指令组成的微程序来实现其功能。这使得复杂指令的实现过程更加清晰和有条理,降低了设计的难度。例如,一条复杂的指令可能需要进行多次内存访问、算术运算和条件判断等操作,通过微程序可以将这些操作分解为多个简单的微指令步骤,按照顺序执行这些微指令就能完成复杂指令的功能。
      • 缺点
        • 速度相对较慢:因为指令的执行需要先读取微程序中的微指令,然后对微指令进行译码和执行,这个过程会引入额外的时间延迟。与硬连线控制相比,微程序控制的指令执行速度通常会慢一些。尤其是在对速度要求极高的应用场景中,微程序控制的速度劣势可能会比较明显。
        • 硬件成本增加:微程序控制需要额外的控制存储器来存储微程序,这增加了硬件的成本和复杂性。同时,为了读取和执行微程序,还需要相应的微指令译码和执行电路,这些硬件资源也会占用一定的芯片面积并且增加功耗。

缓存块的大小的优缺点一览

问题:在许多计算机中,缓存块大小在32到128字节之间。将缓存块大小变大或变小的主要优点和缺点是什么?

  • 答案

    • 增大缓存块大小的优点
      • 提高空间局部性利用率:当程序访问内存数据时,通常会存在空间局部性,即如果访问了一个数据单元,很可能会在不久之后访问其附近的数据单元。较大的缓存块可以一次性将更多相邻的数据加载到缓存中。例如,在处理数组或者连续的文件数据时,一个较大的缓存块可以包含多个连续的数据元素。如果程序后续需要访问这些相邻的数据,就可以直接从缓存中获取,减少了从主存读取数据的次数,从而提高缓存命中率。
      • 减少标记(Tag)存储开销的比例:缓存中的每个块都有一个标记字段用于标识其对应的主存位置。当缓存块变大时,虽然总的缓存容量可能不变,但块的数量会减少。由于标记是和块相关联的,块数的减少意味着标记存储开销在整个缓存存储中所占的比例会降低,从而可以在一定程度上更有效地利用缓存存储空间。
    • 增大缓存块大小的缺点
      • 降低时间局部性利用率:如果程序的数据访问模式没有很好的空间局部性,例如频繁访问不相邻的数据,那么大的缓存块可能会将许多不需要的数据加载到缓存中。这些未被使用的数据占据了缓存空间,可能会导致其他有用的数据被替换出去,从而降低了缓存的效率。而且,加载和替换大的缓存块会花费更多的时间,特别是当只需要块中的一小部分数据时,这种浪费就更加明显。
      • 增加块冲突的可能性:在组相联缓存或者直接映射缓存中,缓存块大小的增加可能会导致更多的块映射到相同的缓存位置(组),从而增加了块冲突的概率。当发生块冲突时,需要频繁地替换缓存块,这会导致更多的主存访问,降低系统性能。
    • 减小缓存块大小的优点
      • 提高时间局部性利用率:对于时间局部性好的程序(即频繁访问相同的数据),较小的缓存块可以更灵活地缓存这些数据。当数据被频繁访问时,较小的块能够更快地被加载和替换,使得缓存可以更快地适应数据访问模式的变化。例如,在一些具有频繁函数调用和局部变量访问的程序中,较小的缓存块可以更好地缓存这些频繁使用的局部数据,减少不必要的数据加载。
      • 降低块冲突概率:较小的缓存块会使更多的主存块能够映射到缓存中不同的位置,减少了多个主存块竞争相同缓存位置的情况,从而降低了块冲突的可能性。这有助于保持缓存中的数据与程序实际访问的数据更加匹配,提高缓存的有效性。
    • 减小缓存块大小的缺点
      • 降低空间局部性利用率:由于块变小,每次从主存加载的数据量减少。如果程序有较好的空间局部性,那么这种方式会导致需要更多次地从主存读取数据,因为每次只能加载少量相邻的数据。这增加了主存访问的次数,降低了缓存系统的整体性能。
      • 增加标记存储开销比例:随着缓存块变小,块的数量会增加。因为每个块都需要一个标记来标识其在主存中的位置,所以标记存储开销在整个缓存存储中所占的比例会增加。这意味着用于存储实际数据的缓存空间相对减少,降低了缓存存储数据的效率。

32位IEEE 754单精度浮点格式

问题:使用32位IEEE 754单精度浮点格式,表示 -0.6875。

  • 答案
    • 首先,将十进制数 -0.6875转换为二进制小数形式。
      • 对于绝对值 0.6875,整数部分为0,小数部分转换过程如下:
        • \(0.6875×2 = 1.375\),取整数部分1;
        • \(0.375×2 = 0.75\),取整数部分0;
        • \(0.75×2 = 1.5\),取整数部分1;
        • \(0.5×2 = 1.0\),取整数部分1,此时小数部分为0,转换结束。
      • 所以,0.6875的二进制表示为0.1011。
    • 然后,根据IEEE 754单精度浮点格式的规则来表示这个数。
      • IEEE 754单精度浮点格式由三部分组成:符号位(1位)、指数位(8位)、尾数位(23位)。
      • 符号位:因为是负数,所以符号位为1。
      • 指数位
        • 先将二进制小数表示为科学计数法形式,\(0.1011 = 1.011×2^{-1}\)
        • 在IEEE 754单精度格式中,指数需要加上一个偏移量,对于单精度,偏移量是127(十进制),也就是\(2^{7}-1\)。这里指数是 -1,加上偏移量后为 -1 + 127 = 126(十进制),126转换为二进制是01111110。
      • 尾数位
        • 在科学计数法形式\(1.011×2^{-1}\)中,去掉前面的1(IEEE 754规定默认前面有个隐藏的1),剩下的011作为尾数位,后面补0补足23位,即01100000000000000000000。
    • 最终, -0.6875在IEEE 754单精度浮点格式下的表示为:1 01111110 01100000000000000000000(按符号位、指数位、尾数位顺序排列)。
  • 解释
    • IEEE 754标准规定了浮点数在计算机中的存储和表示方式,通过将数分为符号、指数和尾数这几个部分来精确表示各种实数范围和精度内的数值。
    • 符号位明确了数的正负性,很直观地表示出数是正数还是负数。
    • 指数位使用偏移量的方式是为了能够表示正指数和负指数,并且可以方便地进行比较和运算。通过加上固定的偏移量,将有符号的指数转换为无符号整数形式存储在规定的位宽中,便于硬件电路对指数进行处理。
    • 尾数位的处理中去掉前面隐藏的1,是因为在规格化的二进制浮点数科学计数法表示下,只要是非零数,小数点左边第一位总是1,所以可以节省这一位的存储空间,将更多的位留给小数部分的尾数,以此来提高浮点数表示的精度。按照这样的规则组合起来,就能准确地用32位来表示给定的浮点数 -0.6875了。

IEEE 754单精度浮点格式是一种用于在计算机中表示实数的标准方法。

一、格式组成

  1. 符号位(Sign bit)
    • 占1位。
    • 0表示正数,1表示负数。
  2. 指数位(Exponent bits)
    • 占8位。
    • 它以偏移码(Excess - K)的形式表示。对于单精度,偏移量\(K = 127\)。这意味着实际的指数值需要减去127才能得到真正的指数值。例如,指数位为\(10000000\)(十进制的128)时,实际指数是\(128 - 127=1\)
  3. 尾数位(Fraction bits)
    • 占23位。
    • 它表示的是小数部分,但有一个隐含的1。在规格化的浮点数中,尾数的第一位默认是1,不存储在这23位中,这23位存储的是小数点后的数字。例如,如果尾数位是\(101000\cdots\),实际的尾数是\(1.101000\cdots\)

二、数值计算

  1. 规格化数(Normalized numbers)
    • 对于一个单精度浮点数\(V\),其计算公式为:
      • 如果符号位\(S\),指数位\(E\),尾数位\(M\),则\(V=(- 1)^{S}\times(1 + M)\times2^{E - 127}\)
    • 例如,一个浮点数的二进制表示为\(0 10000001 01000000000000000000000\)
      • 符号位\(S = 0\)(正数)
      • 指数位\(E=10000001\)(十进制为129),实际指数\(e = 129 - 127 = 2\)
      • 尾数位\(M = 01000000000000000000000\),实际尾数\(m=1.01\)(因为隐含1)
      • 那么该浮点数的值\(V=( - 1)^{0}\times(1 + 0.01)\times2^{2}=1.01\times4 = 4.04\)
  2. 非规格化数(Denormalized numbers)
    • 当指数位全为0时,表示非规格化数。此时,计算公式为\(V=(-1)^{S}\times M\times2^{-126}\),这里的尾数没有隐含的1。
  3. 特殊值
    • 当指数位全为1且尾数位全为0时,表示无穷大(Infinity)。符号位为0表示正无穷,符号位为1表示负无穷。
    • 当指数位全为1且尾数位不全为0时,表示不是一个数字(NaN - Not a Number),通常用于表示无效的运算结果,如\(0/0\)\(\sqrt{-1}\)

子程序和中断服务程序

1. 问题

What is the difference between a subroutine and an interrupt - service routine?

2. 答案

  • 调用方式
    • Subroutine(子程序):由程序中的调用指令(如CALL指令)显式调用。例如,在主程序中当需要执行特定功能时,通过CALL指令调用子程序,子程序执行完后通常通过RET指令返回主程序。
    • Interrupt - service routine(中断服务程序):由硬件中断信号或软件中断指令触发。例如,当外部设备(如键盘)产生一个硬件中断信号时,CPU会暂停当前程序的执行,转而执行对应的中断服务程序来处理该事件;或者程序执行了特定的软件中断指令(如某些操作系统中的系统调用通过软件中断实现)时也会进入中断服务程序。
  • 执行时机
    • Subroutine:在程序执行流程中,由程序员预先安排好调用的时机。比如在一个计算任务中,当需要计算某个复杂函数时调用相应的子程序。
    • Interrupt - service routine:具有随机性,其执行取决于中断事件的发生,不受主程序执行流程的直接控制。例如,定时器中断可能在任意时刻发生,取决于定时器的设定值。
  • 对程序执行的影响
    • Subroutine:执行完后会返回到调用它的下一条指令继续执行主程序,不会改变主程序的正常执行顺序,只是在调用期间暂时转移了执行路径。
    • Interrupt - service routine:中断了主程序的正常执行流程,在中断服务程序执行完毕后,可能会返回到主程序被中断的位置继续执行,但主程序的执行会被暂停一段时间来处理中断事件。
  • 保存上下文环境
    • Subroutine:一般只需要保存返回地址和一些寄存器的值(取决于具体的实现和约定),因为子程序是程序执行流程中可预期的一部分。
    • Interrupt - service routine:需要保存更多的CPU状态信息,包括程序计数器(PC)、所有可能被修改的寄存器等,因为中断可能在程序执行的任意时刻发生,必须确保在处理完中断后能准确恢复主程序的执行状态。

3. 解释

  • 调用方式的解释
    • 子程序是为了将程序中反复使用的功能模块独立出来,方便调用和维护。程序员通过调用指令来使用它,这是一种软件层面的设计机制。而中断服务程序是为了响应外部设备的请求或者处理特殊的软件事件,由硬件或软件触发机制来启动。
  • 执行时机的解释
    • 子程序的调用是在程序设计时就确定好的,是程序逻辑的一部分。中断服务程序则是针对不可预见的外部事件或者特定的软件中断需求,其执行是为了及时处理这些突发事件,确保系统的实时性和可靠性。
  • 对程序执行影响的解释
    • 子程序类似于程序中的一个分支,执行完分支任务后回到主流程。中断服务程序更像是强行插入主程序执行过程中的一段特殊程序,它打断了主程序,处理完事件后再让主程序继续。
  • 保存上下文环境的解释
    • 由于子程序的调用是可预期的,其对CPU状态的影响相对有限,所以只需要简单地保存返回地址和必要的寄存器。而中断可能在任意时刻发生,为了不影响主程序后续的正确执行,必须完整地保存当前CPU的所有关键状态信息,以便在中断处理完毕后准确恢复。

DRMA

问题

假设有两种静态存储芯片:128K×16位(共8片)和1M×8位(共2片),请使用这些存储芯片来实现一个1M×32位的存储器,画出存储器组织的示意图。

参考本题画图即可:

image-20241123141426942

画的很丑,注意是一个3-8译码器。

image-20241205153436209

指令设计

问题

假设一台计算机的指令长度为 16 位,其操作数地址为 4 位。假定设计者需要 16 条零地址指令、31 条一地址指令、14 条二地址指令以及 15 条三地址指令,如何通过具体的操作码范围来设计指令格式以满足这些需求?

答案

  • 三地址指令: 操作码分配 4 位,操作数地址各分配 4 位,格式如下: |操作码(4 位)|地址 1(4 位)|地址 2(4 位)|地址 3(4 位)| 操作码范围为 0000 到 1110(共 15 种不同编码),可用来表示 15 条不同的三地址指令。例如操作码为 0000 时代表一种特定的三地址操作,通过后面三个 4 位地址字段指明参与该操作的三个操作数在内存中的地址。
  • 二地址指令: 操作码扩展为 8 位,操作数地址各分配 4 位,格式如下: |操作码(8 位)|地址 1(4 位)|地址 2(4 位)| 操作码范围为 1111 0000 到 1111 1101(共 14 种不同编码),可用来表示 14 条不同的二地址指令。其操作码的高 4 位固定为 1111,这是因为前面三地址指令已经使用了 0000 到 1110 的操作码,剩下以 1111 开头的编码来扩展表示二地址指令,后 4 位用于进一步区分具体的二地址指令内容,两个 4 位地址字段用于指定两个操作数的地址。
  • 一地址指令: 操作码扩展为 12 位,操作数地址分配 4 位,格式如下: |操作码(12 位)|地址(4 位)| 操作码范围为 1111 1110 0000 到 1111 1111 1110(共 31 种不同编码),用于表示 31 条不同的一地址指令。其操作码的高 8 位基于前面二地址指令未使用完的扩展情况(二地址指令用到 1110 0000 到 1111 1101,剩下以 1111 1111 开头的编码来扩展),后 4 位用于区分具体的一地址指令内容,最后的 4 位地址字段用于指定唯一的操作数地址。
  • 零地址指令: 操作码为 16 位,格式如下: |操作码(16 位)| 操作码范围为 1111 1111 1111 0000 到 1111 1111 1111 1111(共 16 种不同编码),用于表示 16 条不同的零地址指令。其操作码基于前面一地址指令未使用完的扩展情况(一地址指令用到 1111 1111 0000 到 1111 1111 1110,剩下 1111 1111 1111 开头的编码来扩展),由于是零地址指令,不需要操作数地址字段。

解释

这种设计方式运用了扩展操作码的原理,充分利用有限的 16 位指令长度空间来满足不同地址数指令的数量需求。

对于三地址指令,因为数量相对较少(15 条),所以一开始仅用 4 位操作码就能区分它们,同时为每个操作数预留 4 位地址空间,保证指令能准确指定参与操作的操作数位置。

当考虑二地址指令时,由于三地址指令已经占用了一部分操作码范围(0000 到 1110),就利用剩余的以 1111 开头的操作码编码来扩展表示二地址指令,再分配额外 4 位操作码进一步区分不同的二地址指令,以此类推。

一地址指令继续在前述剩余的操作码基础上扩展,利用高 8 位基于二地址指令未用完的扩展空间,后 4 位来区分具体的一地址指令内容,同样为操作数保留 4 位地址空间。

最后零地址指令利用一地址指令剩下的操作码扩展空间,通过 16 位全为操作码的形式来区分 16 条不同的零地址指令,因为这类指令不需要操作数地址字段。

这样的设计使得计算机能够在有限的指令长度下,合理安排操作码和操作数地址,支持多种不同功能和地址数需求的指令,提高了指令集的灵活性和对各类程序逻辑实现的适应性,确保了指令格式既紧凑又能满足实际应用中多样化的指令执行要求。

通过这样逐步扩展操作码的分层设计,能够有条不紊地容纳各类所需的指令,并且可以方便地通过操作码来识别不同类型和功能的指令,进而在硬件执行过程中准确地完成对应的操作任务。

五阶段步骤序列

问题: 给出在一个5 - 阶段RISC处理器上取指和执行指令“Store R6, X(R8)”(假设操作数为32位)所需的步骤序列。

image-20241205155542327

顺序乘法

问题

使用顺序乘法算法,对 5 位无符号数 \(A = 10011\)\(B = 01101\) 执行 \(A×B\) 的运算,并在计算机机器中写出计算过程。

image-20241205160643928