跳转至

Arithmetic for Computer

Introduction

Instructions can be divided into 3 categories

  • memory-reference instructions
    e.g. lw, sw 需要 ALU 计算内存地址
  • arithmetic-logical instructions
    e.g. add, sub, and, or, xor, slt 需要 ALU 进行计算
  • control flow instructions
    e.g. beq, bne, jal 需要 ALU 进行条件判断

Signed Number Formats

  • Sign and magnitude
  • 2's Complement
  • 1's Complement
  • Biased notation

    Why we need biased notation

    上图是 32 位的二进制补码表示,我们可以看到左侧二进制表示,如果看作无符号数,那他们是从小到大排列的;但右侧对应的十进制整数确实分段单增的。
    我们希望有一种这样的表示,能够让右侧的对应的值也单调递增。
    一个想法是对右侧数加上 \(2^31\), 相当于其二进制表示下最高位翻转。

    \([X]_b = 2^n + X\) 从二进制补码到移码,只需要翻转符号位即可。

Arithmetic

  • Addition
  • Substraction
  • Overflow detection: \(C_n \oplus C_{n-1}\)

Constructing an ALU

注: RISC-V 不支持 nor 指令。

Multiplication

Unsigned multiplication

Multiplicand (被乘数) \(\times\) Multiplier (乘数)

  • 如果乘数末位是 1, 加被乘数,否则加 0. 随后将被乘数左移 1 位。

    需要 128+128+64 bit 的寄存器,和一个 128 bit ALU.

  • 不移被乘数,而是移积 (product). 这样 ALU 只需要 64 位。

    Example

  • 这里积最开始只保存在左半部分,右半部分为空。而乘数也要右移,这样我们可以把两个数拼到一起,同时右移。

Signed multiplication

有符号相乘不能直接乘,可以先用符号位决定结果符号,再对绝对值进行乘法。

Booth's Algorithm

思想:如果有一串 1, 减掉乘数的第一个 1, 后面的 1 的序列进行移位,当上一步是最后一个 1 时加。

最开始把积放在高位,被乘数放在低位。(数据保存方法同 2.1.1)默认 \(bit_{-1}=0\)

  • Action

    • 10 - subtract multiplicand from left
    • 11 - nop
    • 01 - add multiplicand to left half
    • 00 - nop

    每个操作结束后都要移位,和 2.1.1 中类似

注意移位时不要改变符号位。

Example

被乘数 Multiplicand 是 0010, 乘数 Multiplier 是 1101.
最开始将积 0000 放在高四位, 1101 作为乘数放在低四位。 最开始 10, 即执行减操作, \(0000-0010=1110\). 答案依然放在高四位,随后右移,以此类推。
注意右移的时候是算术右移, \(bit_{-1}\) 也可能会改变。

Faster Multiplication

32 位数乘 32 位数,相当于 32 个 32 位数相加。(并行加速)

Division

Dividend (被除数) \(\div\) Divisor (除数)

  • 将除数放到高位。从高位开始减,减完将除数右移。商也随之不断左移。如果减完之后是负数,需要还回去。

    7÷2

  • 除数不动,被除数不停地往左移。减到最后一次,如果是小于 0 的,说明不用减了,剩下的就是余数,需要右移移回来。(即将左半部分右移一位)

    因为每次都是将除数和被除数最高位减,减了之后高位就没用了,可以移出去。

    实际上这里结果是 129 位,防止 carry 丢失

    Example

    这里最开始余数就是整个被除数。
    类似乘法,这里的除数只和被除数的高位相减。如果减出来是负数,需要加回去。每次减完之后先左移,然后最右边的一位放商。
    4.1 时其实我们已经结束了除法操作,此时的高位就是我们的余数,但是这最后一次的结果还没有放回到 Reminder 中,因此我们需要再往左移一位为商留出空间,放入后,再把高位余数往右移动以抵消影响。(个人认为可以直接对低位左移一位即可)

带符号的除法:要求余数和被除数符号相同。
除零会产生溢出,由软件检测。

Floating point number

S exp frac
Float 1 8 23
Double 1 11 52

Normalized form: \(N=(-1)^S\times M\times 2^E\)

  • S: sign. \(S=1\) indicates the number is negative.
  • M: 尾数. Normally, \(M=1.frac=1+frac\).
  • E: 阶码. Normally, \(E=exp-Bias\) where \(Bias=127\) for floating point numbers. \(Bias = 1023\) for double.

Note

  • 为什么要把 exponent 放在前面?(因为数的大小主要由 exponent 决定。)
  • 为什么需要 Bias?(移码)
  • 以上是规格化数,尾数前应该有前导 1. 非规格化数的格式见这里

Denormal Numbers

  • \(Exponent=000\ldots 0\)
    非规格化数,让数在较小时能逐渐下溢出。
    \(x=(-1)^s\times((0+Fraction)\times 2^{1-Bias})\)
    注意此时指数是 \(1-Bias=-126/-1022\).
    • Denormal with \(Fraction = 000...0\) we define \(x=0\)
  • \(Exponent=111\ldots 1, Fraction=000\ldots 0\)
    表示 \(\pm \inf\)
  • \(Exponent=111\ldots 1, Fraction\neq 000\ldots 0\) 表示 NaN (Not-a-Number)

Precision

  • signle: approx \(2^{-23}\)
    \(23\times \log_{10}{2} \approx 23\times 0.3 \approx 7\) demical digits of precision.
  • double: approx \(2^{-52}\)
    \(52\times \log_{10}{2}\approx 52\times 0.3 \approx 16\) demical digits of preicsion.

Limitations

  • Overflow: The number is too big to be represented
  • Underflow: The number is too small to be represented

Floating-Point Addition

  • Alignment
    统一指数,一般小的往大的变。因为系统精度位数有限,如果将大的往小的变,那可能会因此损失较大。

    Example

  • The proper digits have to be added

  • Addition of significands
  • Normalization of the result
  • Rounding
Example

FP Adder Hardware

  • step 1 在选择指数大的,并进行对齐。同时尾数可能还要加上前导 1.
  • step 3 是对结果进行标准化。
  • 蓝色线为控制通路,黑色线为数据通路。

Floating-Point Multiplication

\((s1\cdot 2^{e1}) \cdot (s2\cdot 2^{s2}) = (s1\cdot s2)\cdot 2^{e1+e2}\)

  • Add exponents
  • Multiply the significands
  • Normalize
  • Over/Underflow?
    有的话要抛出异常,通过结果的指数判断。
  • Rounding
  • Sign

注意 Exponet 中是有 Bias 的,两个数的 exp 部分相加后还要再减去 Bias.

Example

Data Flow

  • 右边往回的箭头: Rounding 后可能会进位。
  • Incr 用于标准化结果,与右侧 Shift Right 配合。

Accurate Arithmetic

  • Extra bits of precision (guard, round, sticky)

    • guard, round
      为了保证四舍五入的精度。
      结果没有,只在运算的过程中保留。

      Example

    • sticky
      末尾如果不为全 0, 则 sticky 位为 1, 否则为 0.

损失不会超过 0.5 个 ulp.

评论