目录

Crash Course Computer Science 学习笔记

目录
摘要

崔叉叉注
这个系列视频虽然每集时间不长,但是信息密度很大,是目前唯一一个无法倍速且需要字幕的视频。

0 Preview

Carrie Anne Philbin 是个好老师。(树莓派基金会教育总监)


1 Early Computing

1.1 早期计算设备

  1. 算盘(abacus)。
  2. 星盘(astrolabe),可计算船只在海上的经纬度。
  3. 计算尺(slide rule),数学运算辅助工具。
  4. 各种时钟。

1.2 计算机发展史

“At each increase of knowledge, as well as on the contrivance of every new tool, human labour becomes abridged.” —— Charles Babbage

  1. 查尔斯·巴贝奇Charles Babbage)是一个需要被铭记的计算机先驱和天才。

  2. 计算机最早是一种职业,就是算数的。

    “I have read the truest computer of times, and the best arithmetician that ever breathed, and he reduceth thy dayes into a short number” —— Richard Braithwait, 1613.

  3. 莱布尼茨乘法器Stepped Reckoner),一种类似于计算器的设备,通过齿轮运转。

    “… it is beneath the dignity of excellent men to waste their time in calculation when any peasant could do the work just as accurately with the aid of a machine.” —— Leibniz

  4. 预计算表(Pre-Computed Table),就是一堆预先计算好的结果,像字典一样,可以查询。典型应用:射程表。

  5. 差分机(https://en.wikipedia.org/wiki/Difference_engine),由查尔斯·巴贝奇研发的自动化数学机器,可计算多项式、近似对数、三角函数,可储存结果,还可以输出结果。

  6. 分析机Analytical Engine),由查尔斯·巴贝奇设计的一种机械式通用计算机,包含了数学逻辑单元、控制流程、条件分支、循环、内置缓存,还可以获取输入输出,已达到图灵完备级别。

  7. 埃达·洛夫莱斯Ada Lovelace)为差分机编写了假想程序。

    “A new, a vast, and a powerful language is developed for the future use of analysis.” —— Ada Lovelace

  8. 19世纪末,计算设备被用于科学和工程领域,但未触及商业。直到1890年左右的美国人口普查,数据太多而无法通过人力计算按时完成。政府找到赫尔曼·何乐礼Herman Hollerith),发明了打孔卡片制表机(Tabulation Machine)。他随后建立表机器公司(Tabulating Machine Company),这家公司后来于1924年与其它机械制造商合并,成为了国际商业机器股份有限公司(IBM)。


2 Electronic Computing

2.1 电子机械计算机

  1. 哈佛马克1号(https://en.wikipedia.org/wiki/Harvard_Mark_I),用于同盟国。

  2. 继电器Relay):电控机械开关。【注:这里指的是电磁继电器】

    1. 继电器中有一根控制线(control wire),决定电路的开或关。
    2. 控制线(control wire)连接着继电器里的线圈。
    3. 给控制线(control wire)通电,电流流过线圈,产生磁场,吸引电路闭合。
    4. 不通电,在弹簧作品下,电路断开。
  3. 继电器可以连接其他电路或齿轮,完成计算任务。

  4. 继电器有质量,所以不能快速打开或关闭。

  5. 机械结构易损坏。

  6. 又大又热吸引昆虫。1947年9月,操作员从故障继电器上取出一只死蛾子。(Bug的由来)

    “From then on, when anything went wrong with a computer, we said it had bugs in it.” —— Grace Hopper

2.2 电子计算机

崔叉叉注

电子元器件的知识本不复杂,但是由于其自身发展的历史原因,名称前后复用,虽然材料、制作等已经完全不同了,容易引起混乱。简而言之,现在去搜索到的N极管,基本都是指晶体管,也就是硅元素物质,虽然叫“管”,但是既没有玻璃,也不是管状,英文名称可以很好区分,中文名有点乱。早期的N极管,是真空管,有玻璃也是管状。

参考:番外篇:Diode与Triode,BJT的前身电子管是什么东西?

  1. 真空管 / 热电子管Vacuum Tube / Thermionic Valve

    1. 二极管diode
      1. 一个灯泡里有两个电极,正极(带正电)和负极。
      2. 给负极加热,一定程度后会发射电子,称为热电子发射thermionic emission)。
      3. 那么,电子流动起来,就会产生电流。
      4. 只有在给正极充正电的情况下,才会产生上述的现象。
      5. 这种只允许电流单向流动的设备,被称为二极管diode)。
    2. 三极管triode
      1. 二极管具有单向导电性,但是不好控制(要通电的话需要加正电压,然后要放电,再然后加负电压才能不导电)。
      2. 三极管加了一个控制电极,只要给控制电极加正电压火负电压即可。
    3. 真空管比较脆弱,还容易烧坏。
  2. 巨人1号Colossus Mk 1)是第一个大规模使用真空管的计算机。

  3. 埃尼阿克ENIAC)是世界上第一个通用的、可编程的、电子的计算机。

  4. 晶体管transistor

    1. 晶体管也有二极管,三极管,与上文的功能相同,材料不同。
    2. 晶体管虽然叫“管”,但其实不是管状,也没有玻璃,是由掺杂的硅做的。
    3. 二级晶体管,又简称二极管,也叫PN结。
    1. 三极晶体管,又简称三极管,也叫双极性晶体管。

      1. 可以看作两个二极管的组合。

      2. 有两个电极(electrode),C极和E极,和一个控制线(control wire)。

      3. 控制线(control wire)连接门电极(gate electrode),即B极。B极不给电流,不通电,电流越大,通过的电流也越大,有放大功能。

    1. 晶体管比真空管效率高,不易坏,还可以做得很小。

3 Boolean Logic & Logic Gates

3.1 逻辑门:

  1. NOT(三角符号)

  2. AND(D型符号)

  3. OR(飞船符号)

  4. XOR(异或)(飞船 + 笑脸符号)

    /images/Crash_Course_Computer_Science/xor.png
    xor

3.2 用晶体管表示逻辑门

  1. NOT Gate

    /images/Crash_Course_Computer_Science/not_gate.png
    not_gate
  2. AND gate

    /images/Crash_Course_Computer_Science/and_gate.png
    and_gate
  3. OR Gate

    /images/Crash_Course_Computer_Science/or_gate.png
    or_gate

4 Representing Numbers and Letters with Binary

5 How Computers Calculate - the ALU

5.1 ALU——Arithmetic & Logic Unit

5.2 Arithmetic Part

  1. 算术部分(Arithmetic Part):执行数学操作

  2. 异或——>半加法器——>全加法器(一层一层的封装与抽象

    /images/Crash_Course_Computer_Science/XOR--%3EHalf_Adder--%3EFull_Adder.png
    XOR–>Half_Adder–>Full_Adder
  3. 8位加法器

    /images/Crash_Course_Computer_Science/8-bits_adder.png
    8-bits_adder
  4. 减法:将减数取反,再 + 1,再与被减数相加。

    • 举例:
      1. 5 - 1 = 4;
      2. 5 -> 101;
      3. 1-> 001;
      4. 1 取反 -> 110;
      5. 取反 + 1 -> 111;
      6. 101 + 111 -> (1)100;
  5. 上述的加法器,叫行波加法器。优点是直观简单,缺点是速度慢,因为进位(Carry)需要一层层计算,最后才能确定。

  6. 现在高级的设备用的是超前进位加法器(Carry-Look-Ahead-Adder),基本原理是进位(Carry)其实在两个加数已知的情况下,可以直接得出,不需要等一级一级的计算结果。

  1. ALU可以做这些事
/images/Crash_Course_Computer_Science/alu_can_do.png
alu_can_do
  1. 低端ALU不能直接乘或者除,没有专门的电路来处理。

5.3 Logic Part

  1. 逻辑部分(Logic Unit):执行逻辑操作,以及简单数值测试

    /images/Crash_Course_Computer_Science/check_0.png
    check_0
  2. ALU的抽象

    /images/Crash_Course_Computer_Science/alu_abstraction.png
    alu_abstraction

6 Registers and RAM

6.1 存储输入的值

  1. 关键:把输出作为输入返回。

  2. 一个只能存储0的电路

    /images/Crash_Course_Computer_Science/store_0.png
    store_0
  3. 一个只能储存1的电路

    /images/Crash_Course_Computer_Science/store_1.png
    store_1
  4. 与或锁(add-or latch):可以写入(Set)或者重置(Reset)。

    /images/Crash_Course_Computer_Science/add-or_latch.png
    add-or_latch
  5. 门锁(gated latch):有一个输入与一个控制。控制打开保存输入,控制关闭保留之前的输入。

    /images/Crash_Course_Computer_Science/gated_latch.png
    gated_latch
  6. 记录一下自己画的过程留作纪念

    /images/Crash_Course_Computer_Science/process.png
    process
  7. 这里缺少了读取的电路,补充一下。这里画的逻辑没问题,但是实际中,输入输出数据线复用了一条,这个软件我不知道如何操作才能实现这样的效果

    /images/Crash_Course_Computer_Science/write_and_read_data.png
    write_and_read_datar

6.2 寄存器(Register)

  1. 一组门锁(gated latch)组成寄存器(register),门锁数量叫做位宽。

  2. 8位寄存器

    1. 把8个门锁(gated latch)并排放置,用一根线连接所有的控制线。

    2. 打开控制线,输入8位的数字。

    3. 关闭控制线,数据已存储。

      /images/Crash_Course_Computer_Science/8-bit_register.png
      8-bit_register

6.3 内存

6.3.1 内存布局

  1. 并排放置不可取,在门锁多的情况下线太多,太占空间,而且不能精准的操作某一个存储单元。

  2. 使用网格矩阵。

    /images/Crash_Course_Computer_Science/16_latch_matrix.png
    16_latch_matrix
  3. 这张网格矩阵的单元放大图值得好好看,看不懂没法理解为什么16X16需要35根线。

    /images/Crash_Course_Computer_Science/write_data.png
    写数据
    /images/Crash_Course_Computer_Science/write_data.png
    读数据
  4. 详解:

    1. 网格矩阵形成了一个二维坐标系,任何一点(即那个单个的存储单元),如果需要被定位到,需要X轴的线,和Y轴的线,同时被激活。
    2. 也是这16+16=32根线,组成了门锁矩阵。把这两根线,称为定位线 / 寻址线。
    3. 把这两根线,用与(AND)门连接,那么只有同时为1,最终结果才会为1,这个与(AND)之后的线,我们称为激活线(自己造的名字)。
    4. 在寄存器部分。我们已经知道,一个存储单元需要一个控制线,一个数据线才能写入+储存数据,这里还要加一个读取线,用来读数据。那么就是写入控制线,读取控制线,数据传输线,一共3条线。
    5. 并排放置的话,写入控制线,读取控制线,共用一个的情况,一次可以操作一排存储单元,如果要操作单个,就需要更多的线。
    6. 现在变成了网格矩阵,那么把之前的激活线与写入控制线,读取控制线,数据传输线各自用与(AND)门连接,如图所示,三条线即可以共用。因为激活线每次只会激活一个存储单元,其他的存储单元的激活线是0,与三条线与(AND)结果还是0,不影响。
    7. 所以一共需要16(X轴定位线) + 16(Y轴定位线) + 1(写入控制线) + 1(读取控制线) + 1(数据传输线) = 35 根线。

6.3.2 静态随机存取器(Static Random Access Memory - SRAM)

  1. 多路复用器(Multiplexer):

    1. 我们现在学习的内存,是16 X 16 = 256 bits,那么经纬度地址就是0 - 15,可以用一个4位2进制数表示。

    2. 多路复用器,可以让我们用一个4位2进制数表示10进制的0 - 15,即找到我们需要的存储单元。

      /images/Crash_Course_Computer_Science/multiplexer.png
      multiplexer

  2. 把多路复用器(Multiplexer)与存储单元结合到一起,再抽象起来,变成一块完整的大存储单元(一个存储单元可以存1比特,这个整合到一起的可以存256比特,即32字节)。

    /images/Crash_Course_Computer_Science/32-bytes_memory.png
    32-bytes_memory
  3. 把8个大存储单元并列起来,每次给8个大存储单元相同的地址,就可以储存8比特,即1字节,一共可以存储256字节。

    /images/Crash_Course_Computer_Science/256-bytes_memory.png
    256-bytes_memory
  4. 再把并列起来的大存储单元抽象,看作一个整体,称为内存(SRAM)。

    /images/Crash_Course_Computer_Science/SRAM.png
    SRAM

6.3.3 一个问题探究

一个问题:我们已经知道了内存的原理,并且把数据存放在内存。那么有一个问题,CPU如何知道我们需要的值,在内存的哪里?换言之,如果我们计算 2 + 3 = 5,然后我们现在需要5,并把5存在内存里,CPU怎么知道哪个地址的值,就是我们需要的5?


答案

答案:CPU并不知道,是我们的程序告诉它的。

详解:这个问题之所以困扰我很久(几小时)的原因,是我在学习硬件的时候,忽略了软件的存在。CPU等硬件是很呆的,它本身不知道自己要干嘛,它不会自己去计算 2 + 3 的,是我们写的软件告诉它这么做的。


图解:

/images/Crash_Course_Computer_Science/conversation_1.png /images/Crash_Course_Computer_Science/conversation_2.png
/images/Crash_Course_Computer_Science/javap.png
javap
  1. 在真实程序中,程序并不会像图里一样,与CPU你来我往,而是把所有指令按顺序发给CPU,称为指令集。所以,变量与地址的维护,是由程序完成的,CPU只负责接命令干活,这也是为什么各个视频教程里,讲到CPU与内存的时候,都是从地址出发,因为CPU实际上已经拿到地址了
  2. 程序对变量与地址的维护,就是另一个话题了,实质是程序对内存的管理,例如Java中的内存模型,是对内存的抽象。

7 The Central Processing Unit (CPU)

7.1 把这两个视频结合到一起看,就会很清晰:

  1. CPU指令的执行
  2. The Central Processing Unit (CPU)

7.2 CPU 组成:控制单元(Control Unit)+ 运算单元(Arithmetic Unit)

7.2.1 控制单元(Control Unit):

  1. 操作控制器(Operation Controller)
  2. 时序产生器(Timing Generator)
  3. 程序计数器(Program Counter)
  4. 地址寄存器(Instruction Address Register)
  5. 指令译码器(Instruction Decoder)
  6. 指令寄存器(Instruction Register)
  7. 等等等等

7.2.2 运算单元(Arithmetic Unit):

  1. 运算逻辑单元(ALU)
  2. 寄存器(Register) / 数据寄存器 / 缓冲寄存器(Data Register)
  3. 累加器(Accumulator)
  4. 状态寄存器(Status Register)
  5. 等等等等

7.2.3 CPU工作步骤:

  1. 指令由两部分组成:指令码(表示这条指令要干啥) + 操作数(要操作的数字或地址,可没有)。

  2. 获取阶段(Fetch Phase)

    1. 程序计数器(Program Counter)把指令地址给地址寄存器(Instruction Address Register)。
    2. 地址寄存器(Instruction Address Register)去内存(其实不一定就是内存,方便理解不展开)中取到这条指令(Instruction),交给指令寄存器(Instruction Register)。
    3. 指令寄存器(Instruction Register)把指令交给指令译码器(Instruction Decoder)。
  3. 解析阶段(Decode Phase)

    1. 指令译码器(Instruction Decoder)解析指令,其实是与CPU指令集比对。
  4. 执行阶段(Execute Phase)

    1. 假设这条指令的操作数是一个地址,那么指令译码器(Instruction Decoder)会把地址交给地址寄存器(Instruction Address Register)。

    2. 地址寄存器(Instruction Address Register)去内存取到数据,交给寄存器(Register) / 数据寄存器 / 缓冲寄存器(Data Register)。

    3. 流程结束,地址寄存器(Instruction Address Register)+1。

  5. 重复获取阶段(Fetch Phase)

  6. 重复解析阶段(Decode Phase):指令为+1操作。

  7. 重复执行阶段(Execute Phase)

    1. 寄存器(Register)把数据给运算逻辑单元(ALU)。

    2. 操作控制器(Operation Controller)发出一个+1操作信号给运算逻辑单元(ALU)。

    3. ALU +1 之后,把结果放到累加器(Accumulator)。

      注:累加器(Accumulator)实质也是一个寄存器(Register),所以Carrie Anne的视频里,用寄存器A、B来将流程也没毛病。

  8. 流程结束,地址寄存器(Instruction Address Register)+1。

7.2.4 再来看这个架构图就会很清晰了。

/images/Crash_Course_Computer_Science/intel_4004.png
intel_4004
/images/Crash_Course_Computer_Science/cpu.png
cpu

8 Instructions & Programs

8.1 指令集实质是对电路计算的提升与抽象,程序实质是对指令集的提升与抽象。

8.2 几个信概念:

  1. 指令长度(Instruction Length)
  2. 可变长度指令(Variable Length Instruction)
  3. 立即值(Immediate Value)

8.3 Intel 4004 指令集

/images/Crash_Course_Computer_Science/intel_4004_instructions.png
intel_4004_instructions

9 Advanced CPU Designs

9.1 提升CPU性能的若干方式

  1. 早期:提升晶体管(transistor)质量。
  2. 增加额外电路组成,用来处理常规指令集需要长时间处理的内容,例如图形、视频编码解码、加密解密等。
  3. 增加额外指令集,同时保留过去的指令集,用于向下兼容性(Backwards Compatibility)。
  4. 增加高速缓存(Cache)。
    1. 缓存命中(Cache Hit)。
    2. 缓存未击中(Cache Miss)。
    3. 缓存一致性问题:每一个缓存存储单元有一个脏位(Dirty Bit),用来标记是否需要同步缓存与内存数据。
  5. 指令流水线(Instruction Pipelining):实质就是并行(parallelize)处理几个指令。
    1. 指令之间的互相依赖问题。
      1. 低端处理器:根据下一条指令判断是否暂停流水线(Pipeline Stall)。
      2. 高端处理器:乱序执行(out-of-order execution)——根据依赖动态重排序指令顺序。
    2. 条件指令(Conditional) / 跳跃指令(Jump)
      1. 低端处理器:暂停流水线(Pipeline Stall)等待最终结果。
      2. 高端处理器:
        1. 分析预测(Branch Predicting)——预测后续的指令执行。
        2. 推测执行(Speculative Execution)——直接分析预测(Branch Predicting)中预测的路径,再根据最终结果调整,是否需要流水线冲洗(Pipeline Flush)。
  6. 超标量(Superscalar)
  7. 多核CPU

崔叉叉注
后续内容比较熟悉,且越讲越远,笔记暂时空缺,之后补上。

10 Early Programming

11 The First Programming Languages

12 Programming Basics

13 Intro to Algorithms

14 Data Structures

15 Alan Turing

16 Software Engineering

17 Integrated Circuits & Moore’s Law

18 Operating Systems

19 Memory & Storage

20 Files & File Systems

21 Compression

22 Keyboards & Command Line Interfaces

23 Screens & 2D Graphics

24 The Cold War and Consumerism

25 The Personal Computer Revolution

26 Graphical User Interfaces

27 3D Graphics

28 Computer Networks

29 Computer Networks

30 The World Wide Web

31 Cybersecurity

32 Hackers & Cyber Attacks

33 Cryptography

34 Machine Learning & Artificial Intelligence

35 Computer Vision

36 Natural Language Processing

37 Robots

38 Psychology of Computing

39 Educational Technology

40 The Singularity, Skynet, and the Future of Computing