11 | 二进制编码:“手持两把锟斤拷,口中疾呼烫烫烫”?
理解二进制的“逢二进一”
十进制的数,转化成二进制,使用短除法就可以了
字符串的表示,从编码到数字
采用二进制序列化会比存储文本省下不少空间。
12 | 理解电路:从电报机到门电路,我们如何做到“千里传信”?
- 电报信号的优势。
- 第一,信号的传输距离长时延小
- 第二,输入信号快
电报机本质上就是一个“蜂鸣器+长长的电线+按钮开关”。
理解继电器,给跑不动的信号续一秒
- 问题:U电池固定,电线很长时R大,U蜂鸣器小,所以电压不够蜂鸣器不会响
- 解决:线路太长时要分段,多次放大信号
继电器放大信号
反向器(Inverter)
13 | 加法器:如何像搭乐高一样搭电路(上)?
在计算机硬件层面设计中最基本的单元是门电路。
异或门和半加器
8位的无符号整数的加法。
输入一共是4种组合,00、01、10、11。得到的结果,也不复杂。
- 先计算个位。输入0.0和1.1时个位为0 。输入1.0时个位为1
- 异或门实现整数加法
- 其次计算进位。当输入为1.1时发出进位信号
半加器(Half Adder):与门加或门
- 问题:二位加法需要处理三个信号(两个加数和上一位的进位信号)
- 用两个半加器和一个或门,就能组合成一个全加器。
- 第一个半加器,处理两个加数,得到是否进位X和对应的二个数加和后的结果Y。
- 第二个半加器处理二位(Y)和上一位的进位信号。
- OR门处理两个半加器的进位信号
x和y不可能为(1,1)所以不用考虑两个半加器同时进位
换句话说:十进制中两个位数相加和一定小于20(进位两次)
14 | 乘法器:如何像搭乐高一样搭电路(下)?
顺序乘法的实现过程
二进制的乘法
- 优点:乘法退化成了位移和加法。
- 位移的原理斜着错开位置去接线路
- 实现:加法器、一个可以左移一位的电路和一个右移一位的电路
被乘数每次只x乘数的个位,计算完储存结果后分别左移和右移一位
顺序计算的缺点:慢。
多组操作不能同时进行,下一组总要依赖上一组的结果。导致整个算法是"顺序"的。所以计算速度和计算的位数有关。时间O(N)
并行加速方法
顺序执行方法每个中间结果都只能和下一位相乘。并行执行中是每个中间结果相乘
电路并行
慢的原因
-
核心“顺序”计算
- 每通过一个门电路,我们就要等待门电路的计算结果,就会产生一个门电路延迟
-
其次时钟频率
-
问题:并行计算。怎样才能让高位不需要等待低位的进位结果,而是把低位的所有输入信号都放进来,直接计算出高位的计算结果和进位结果呢?
增加晶体管可以利用电路天然的并行性来达到更低的门延迟和低cpi
(指令平均周期数 Cycle Per Instruction)
总结延伸
通过ALU和门电路,搭建出来了乘法器。 硬件电路有一个很大的特点,那就是信号都是实时传输的。
15 | 浮点数和定点数(上):怎么用有限的Bit表示尽可能多的信息?
浮点数的不精确性
-
问题:我们用32个比特,能够表示所有实数吗?
- 解决:不能。32个比特,只能表示2的32次方个不同的数。如果表示的数总量超过这个数,就会有两个不同的数的二进制表示是一样的。
-
问题:我到底应该让这40亿个数映射到实数集合上的哪些数,在实际应用中才能最划得来呢?
-
解决:需要准确表达的用累加的方式一一对应(定点数)。其余用乘法结合指数表示来扩大颗粒度以扩大表示的区间
定点数的表示
BCD编码(Binary-Coded Decimal):二进制来表示十进制的编码方式。
用32个比特,来表示从0到999999.99这样1亿个实数。
缺点:
- 虽然可以表示一个精确的数,但是浪费
- 精确程度和小数部分占的位数有关,整体表示的范围和整数部分的表示有关
浮点数的表示
单精度类型
0.5为例子。0.5的符号为s应该是0,f应该是0,而e应该是-1,也就是
0.5 = ( − 1 ) 0 × 1.0 × 2 − 1 = 0.5 0.5= (-1)^0×1.0×2^{-1}=0.5 0.5=(−1)0×1.0×2−1=0.5,对应的浮点数表示,就是32个比特。
总结延伸
在这样的表示方式下,浮点数能够表示的数据范围一下子大了很多。随着指数位e的值的不同,小数点的位置也在变动。BCD编码的实数,就是小数点固定在某一位的方式,我们也就把它称为定点数。