9.高级CPU设计

0、概念梳理

  • 缓存:在CPU中的小块RAM,用于存储批量指令。
  • 缓存命中:想要的数据已经在缓存里
  • 缓存未命中:想要的数据不在缓存里
  • 脏位:缓存里每块空间,有个特殊标记,叫脏位,用于检测缓存内的数据是否与RAM一致。
  • 多核处理器:一个CPU芯片中,有多个独立处理单元。
  • 总线bus:cpu和内存之间的传输线,成为瓶颈了,就需要缓存

    1、现代CPU如何提升性能:

    早期通过加快晶体管速度,来提升CPU速度。但很快该方法到达了极限。
    后来给CPU设计了专门除法电路+其他电路来做复杂操作:如游戏,视频解码,加密,图形

    2、缓存:

    为了不让CPU空等数据,在CPU内部设置了一小块内存,称为缓存,让RAM可以一次传输一批数据到CPU中。(不加缓存,CPU没位置放大量数据)
    缓存也可以当临时空间,存一些中间值,适合长/复杂的运算。
    空等原因:从RAM到CPU的数据传输有延迟(要通过总线,RAM还要时间找地址、取数据、配置、输出数据)。

    3、缓存同步:

    缓存同步一般发生在CPU缓存已满,但CPU仍需往缓存内输入数据。此时,被标记为脏位的数据会优先传输回RAM,腾出位置以防被覆盖,导致计算结果有误。

    4、指令流水线:

    作用:让取址→解码→执行三个步骤同时进行,这3个步骤用的是cpu的不同部门。并行执行指令,提升CPU性能。
    原本需要3个时钟周期执行1个指令,现在只需要1个时钟周期。

设计难点:

  1. 指令(数据)具有依赖性
    1. 停止流水线等待
    2. 动态排序依赖的指令(乱序运行)比较高级
  2. 条件跳转
    1. 预测分支(高端CPU)

image.png

5、一次性处理多条指令

超标量处理器
设计目的:一次性处理多条指令(取指令+解码) 会更好,多条指令要 ALU 的不同部分,就多条同时执行
再进一步,加多几个相同的电路执行出现频次很高的指令,比如很多 CPU 有四个, 八个甚至更多 完全相同的ALU
image.png

6、同时运行多个指令流(多核CPU)

多核处理器:一个CPU芯片中,有多个独立处理单元。但因为它们整合紧密,可以共享一些资源。
共享缓存->多核合作运算

7、超级计算机(多个CPU)

在一台计算机中,用无数个CPU,做怪兽级的复杂运算,如模拟宇宙形成。
40960个cpu256核心1.45GHhz->
9.3 亿亿次浮点数运算

10.早期的编程方式

1、早期,程序如何进入计算机

程序必须人为地输入计算机。早期,电脑无内存的概念,人们通过打孔纸卡等物理手段,输入数据(数字),进入计算机。

2、早期计算机的编程

  • 打孔纸卡/纸带:在纸卡上打孔,用读卡器读取连通电路,进行编程。原因,穿孔纸卡便宜、可靠也易懂。62500张纸卡=5MB数据
  • 插线板:通过插拔线路的方式,改变器件之间的连接方式,进行编程。
  • 面板拨开关(1980s前):通过拨动面板上的开关,进行编程。输入二进制操作码,按存储按钮,推进至下一个内存位,直至操作完内存,按运行键执行程序。(内存式电脑)

    3、现代计算机基础结构——冯诺依曼计算机

    冯诺依曼计算机的标志是,一个处理器(有算术逻辑单元)+数据寄存器+指令寄存器+指令地址寄存器+内存

    简单来说

    就是指令+数据=程序呗

    11.编程语言发展史

    0、概念梳理

    伪代码:用自然语言(中文、英语等)对程序的高层次描述,称为“伪代码”
    汇编器:用于将汇编语言装换成机器语言。一条汇编语句对应一条机器指令。
    助记符(汇编器):每个操作码分配一个简单名字

    1、早期二进制写代码

    计算机能处理二进制,也只能处理二进制
    先前都是硬件层面的编程,硬件编程非常麻烦,所以程序员想要一种更通用的编程方法,就是软件。
    早期,人们先在纸上写伪代码,用”操作码表”把伪代码转成二进制机器码,翻译完成后,程序可以喂入计算机并运行。

    2、汇编器Assembler&助记符

    背景:1940~1950s,程序员开发出一种新语言, 更可读 更高层次。每个操作码分配一个简单名字,叫”助记符”。但计算机不能读懂“助记符”,因此人们写了二进制程序“汇编器来帮忙”
    作用:汇编器读取用”汇编语言”写的程序,然后转成”机器码”。
    有一个很好用的功能:自动分析 JUMP 地址,加一个标签,就不会改很多代码,屏蔽底层细节

    3、最早高级编程语言“A-0”

    汇编只是修饰了一下机器码,一般来说,一条汇编指令对应一条机器指令,所以汇编码和底层硬件的连接很紧密,汇编器仍然强迫程序员思考底层逻辑。

1950s,为释放超算潜力,葛丽丝·霍普博士,设计了一个高级编程语言,叫 “Arithmetic Language Version 0”,一行高级编程语言 可以转成几十条二进制指令。但由于当时人们认为,计算机只能做计算,而不能做程序,A-0未被广泛使用。
过程:高级编程语言→编译器→汇编码/机器码

4、开始广泛应用的高级编程语言FORTRAN

1957年由IBM1957年发布,平均来说,FORTRAN 写的程序,比等同的手写汇编代码短 20 倍, FORTRAN 编译器会把代码转成机器码。

5、通用编程语言——COBOL

1959年,研发可以在不同机器上通用编程语言。
最后研发出一门高级语言:”普通面向商业语言”,简称 COBOL
每个计算架构需要一个 COBOL 编译器,不管是什么电脑都可以运行相同的代码,得到相同结果。 write once, run anywhere.

6、现代编程语言:1960s-2000

1960s起,编程语言设计进入黄金时代。
1960 :LGOL, LISP 和 BASIC 等语言
70年代有:Pascal,C 和 Smalltalk
80年代有:C++,Objective-C 和 Perl
90年代有:Python,Ruby 和 Java
新千年 Swift, C#, Go

*7、安全漏洞&补丁由来:

在1940年代,是用打孔纸带进行的,但程序出现了问题(也就是漏洞),为了节约时间,只能贴上胶带也就是打补丁来填补空隙,漏洞和补丁因此得名。

12. 编程原理-语句和函数

语法syntax

  1. assignment statement赋值语句 a=1
  2. Control Flow Statements.控制流语句(Conditional Statements.) if
  3. conditional loop 条件循环 while for循环

    函数

    还可以函数调用函数
    函数不超过100行
    模块化编程->现代
    常用函数集合->库 网络 图像 音乐

    13.算法入门

    算法概念:解决问题的具体步骤
    排序的基础算法:选择排序O(n2),归并排序O(n*log n)
    算法复杂度:算法的输入大小和运行步骤之间的关系,表示运行速度的量级
    图搜索:
    暴力法:O(n!)
    Dijkstra算法:O(n2) ->改进O(n log n+1)
    image.png
    精華总结:根据情况合理决定 用现有算法 还是自己写新算法

    14.数据结构

    数组

    image.png
    数组存储在内存的结构
    取数据:查到起始位置,加上偏移量,bingo
    类库包含了数组的排序
    字符串也是数组一种,最后一个是截止符
    image.png
    数组还可以扩展成多维数组image.png
    特点:数组的大小是固定的,无法动态改变,插入比较麻烦

    结构体

    概念:多个变量打包在一起
    image.png
    可以把结构体弄成数组
    比如User[]=[{no:1,age:18},{no:2,age:22}]

    链表

    基本单位:
    一个叫做节点(node)的结构体,一个变量存值,另一个变量存储下一个的地址
    class Node{
    Integer value;
    Long nextAddress;
    }
    image.png
    抽象成
    image.png
    插入,删除方便,容易重新排序,两端缩减,分隔,倒序

    队列

    FIFO先进先出
    基于链表

    基于链表
    LIFO后进先出

    链表2个指针就是简单树
    image.png

    也可以由链表构成

    总结

    选择正确数据结构会让工作更简单,所以花时间考虑用什么数据结构是值得的
    大多数编程语言自带了预先做好的数据结构,关键在于选择

    15.阿兰图灵

    图灵完备:强大的计算机,图灵机是很强大的计算模型

    问题1

    是否存在一种算法,输入正式逻辑语句,输出准确的”是”或”否”答案?
    答案:不存在
    原因:
    提出了一种假想的计算机,现在叫”图灵机”,图灵机是一台理论计算设备,还有一个状态变量,保存当前状态,还有一组规则,描述机器做什么,规则是根据 当前状态+读写头看到的符号,决定机器做什么,结果可能是在纸带写入一个符号,或改变状态,或把读写头移动一格,或执行这些动作的组合,
    比如:读一个以零结尾的字符串,并计算1的出现次数是不是偶数,这个是可以计算的,只要有足够的规则,状态和纸带 可以创造任何东西
    推论:有没有办法在不执行的情况,弄清会不会停机?所以在运行前知道 会不会出结果很有用

想象有一个假想图灵机, 输入:问题的描述 + 纸带的数据 输出 Yes 代表会”停机”,输出 No 代表不会
如果有个程序, H 无法判断是否会”停机”,意味着”停机问题”无法解决
为了找到这样的程序,图灵用 H 设计了另一个图灵机
如果 H 说程序会”停机”,那么新机器会永远运行(即不会停机),如果 H 的结果为 No,代表不会停机,那么让新机器输出 No,然后”停机”,实质上是一台和 H 输出相反的机器,叫做异魔,如果把 异魔 的描述,作为本身的输入会怎样
但如果 H 说异魔会停机,那么异魔会进入无限循环,因此不会停机
如果 H 说异魔不会停机,那么异魔会输出 No 然后停机
所以 H 不能正确判定 停机问题,因为没有答案

结论:

丘奇和图灵证明了计算机的能力有极限,无论有多少时间或内存,有些问题是计算机无法解决的

工作

二战时候给盟军解密工作

提出人工智能

图灵测试:
想像你在和两个人沟通 不用嘴或面对面,而是来回发消息,可以问任何问题,然后会收到回答,但其中一个是计算机,如果你分不出哪个是人类,哪个是计算机,那么计算机就通过了图灵测试
“公开全自动图灵测试,用于区分计算机和人类” 简称”验证码” 防止机器人发垃圾信息等

16.软件工程

将方法放在对象里面
对象可以在拥有自己的变量和方法,还有属性
面向对象编程-封装组件,隐藏复杂度
辅助:接口api和文档帮助调用者快速理解,也便于自己整理,IDE其他工具啥的
封装继承多态
debug,注释,版本控制svn git,测试