Lec 1 计算机体系架构的介绍
计算机架构师实际在做什么?
计算机架构师设计和优化计算机系统的硬件结构,以提高性能、能效和可靠性。他们的工作包括设计处理器、内存系统、输入输出设备和其他组件,并且需要考虑成本、功耗和物理限制。他们经常使用仿真和建模工具来预测设计的性能,并与软件工程师合作确保硬件和软件的协同工作
计算机简史
早期ENIAC、EDVAC 和 EDSAC
ENIAC (Electronic Numerical Integrator and Computer):
- NIAC由埃克特(Eckert)和莫克利(Mauchly)于1943-1945年在宾夕法尼亚大学设计和建造。
- 技术特点:它是第一台完全数字化、电子化、操作的通用分析计算器。ENIAC的出现标志着计算机技术从机械和电子混合系统向全电子数字计算机的重要进步
- 规模:ENIAC重达30吨,占地面积72平方米,功耗高达200千瓦。
- 性能:
- 每分钟能读取120张卡片。
- 加法操作耗时约200微秒,除法操作耗时约6毫秒
- ENIAC最初应用于弹道计算。例如,计算炮弹射击时的角度需要考虑多个因素,如位置、顺风、横风、空气密度、温度、炮弹重量和推进剂量等。ENIAC的高速计算能力使得这些复杂的弹道计算成为可能,帮助军事应用提高了精度和效率。
EDVAC (Electronic Discrete Variable Automatic Computer):
- ENIAC的编程系统是外部的
- 指令序列独立于计算结果执行
- 需要人工干预以“乱序”执行指令
- EDVAC由Eckert、Mauchly和von Neumann在1944年设计,旨在解决这一问题
- 解决方案是存储程序计算机
- “程序可以像数据一样被操作” •
- 1945年首次发布了《EDVAC报告草案》,但只有von Neumann的签名!
- 这篇报告毫无疑问是计算机体系结构中最有影响力的论文
- ENIAC的编程系统是外部的
EDSAC (Electronic Delay Storage Automatic Calculator):
- 1950年建于剑桥大学,是第一台实用化的存储程序计算机。
- 使用了水银延迟线存储器
IBM 650 和 IBM 360
- IBM 650:
- 1950年代中期发布的第一台大规模生产的计算机,被广泛用于商业和科学计算。
- 使用了磁鼓存储器。
- IBM 360:
- 1960年代发布,标志着现代计算机系统的一个重要里程碑。
- 统一了多个型号的计算机体系结构,支持多种编程语言和操作系统。
- 西摩·克雷 – CDC 6600 和 Cray 1
- CDC 6600:
- 由西摩·克雷设计,于1964年发布,是世界上第一台超级计算机。
- 采用了创新的分布式处理器和高效的流水线技术
- Cray 1:
- 1976年发布,是第一台使用向量处理器的超级计算机。
- 以其高性能和创新的C形设计而著名
- CDC 6600:
- IBM 650:
微处理器和个人计算机
多核处理器
手机
存储程序计算机的出现
- 内部存储器
- ENIAC计算机(1946年)使用插板作为内部存储器,是一种只能读取的存储程序计算机。
- EDVAC计算机(1947年概念提出)提出了可读写存储器的概念,允许程序和数据存储在同一存储器中,大大提高了灵活性和效率
早期计算机的主要问题是可靠性,指的是计算机能够持续运行而不发生故障的能力。平均故障间隔时间(MTBF)是衡量指标。但是最可靠的是20分钟。
到20世纪50年代中期,计算机技术的几个特点:
- 硬件昂贵
- 存储容量小:只有1000个字
- 内存访问速度慢,比CPU慢10-50倍
- 程序员需要与机器直接打交道
- 设计复杂的控制电路来执行指令是当时的主要设计关注点,而不是指令解码速度或算术逻辑单元(ALU)操作的速度
在早期计算机设计中,使用了单一累加器作为主要的运算寄存器。这种设计借鉴了计算器的设计理念。 为什么? 寄存器昂贵:在那个时代,寄存器(用于暂存数据的高速存储单元)非常昂贵。因此,为了节省成本,计算机设计中只使用了一个主要的运算寄存器

抽象层

IMPORTANT
计算机体系结构本质上是抽象层的设计
那抽象层的好处是什么?
在一代产品内的环境稳定性(Environmental stability within generation)
跨代产品的环境稳定性(Environmental stability across generations)
大量单元的一致性(Consistency across a large number of units)
抽象层的结果是什么?
- 激励应用创新(Enticement for application innovation)
- 简化了设计
- 提供的稳定开发环境,可以快速迭代和发布
- 鼓励创建可重用的基础设施(Encouragement to create reusable foundations)
- 工具链
- OS
- Library
技术是计算机设计的主导
推动(push)因素通常是由技术的进步和创新驱动,它们为计算机科技的发展奠定了基础和前进方向。
- Transistors(晶体管):晶体管的发明是从真空管到固态电子设备的重大进步,极大地提高了计算机的速度、可靠性和效率。
- Integrated circuits(集成电路):将多个晶体管集成到一个芯片上,使得计算机的尺寸缩小,功耗降低,同时性能提升。
- VLSI(超大规模集成电路,初期):进一步提高了集成电路的密度和复杂度,为后来的处理器和存储器提供了更大的性能和功能。
- Flash memories(闪存):非易失性存储技术的发展,提供了更快的数据访问速度和更大的存储容量,广泛用于固态硬盘和移动设备中。
拉动(pull)因素主要是由市场需求和用户需求驱动,它们直接影响到计算机科技的应用和使用场景。
- Core memories(核心内存):早期计算机中使用的一种稳定且可靠的内存存储技术,满足了用户对数据持久性和稳定性的需求。
- Magnetic tapes(磁带):提供了大容量、低成本的数据存储和备份解决方案,适用于需要长期存储和大规模数据处理的场景。
- Disks(磁盘):硬盘驱动器提供了快速、随机访问的数据存储解决方案,满足了用户对数据快速访问和处理的需求。
相互作用(push and pull)指的是技术推动和市场需求之间的双向影响,它们共同推动了计算机科技的进步和发展。
- ROMs, RAMs(只读存储器和随机存储器):ROM提供了固化程序和数据的存储解决方案,而RAM则支持动态数据存储和快速访问,二者共同满足了计算机系统中对数据存储和处理的需求。
- VLSI(超大规模集成电路):VLSI技术既是技术推动(通过集成更多的功能和性能)、又是市场拉动(满足更高计算需求)的双重作用体现。
- Packaging(封装技术):有效的封装技术不仅保护芯片,还提高了其性能和可靠性,使得计算机硬件可以更好地应对环境和使用条件。
- Low Power(低功耗技术):随着移动计算和嵌入式设备的普及,低功耗技术的推广满足了市场对长续航时间和节能环保的需求,同时也推动了芯片设计和制造技术的发展
软件的影响呢?
随着人们编写程序和使用计算机,我们对编程和程序行为的理解不断提高。 这对计算机体系结构虽然影响深远但速度较慢。 现代的架构师必须重视软件和编译问题。
体系架构是在限制下的工程设计,考虑因素有哪些
系统在目标应用中的整体性能
- 平均情况和最坏情况
制造芯片及支持系统的成本
运行系统所需的功耗
- 峰值功耗和每次操作的能量消耗
系统的可靠性
- 软错误和硬错误
芯片设计的成本(工程师、计算机、CAD工具)
- 在许多情况下成为限制因素,较少的独特芯片能够得到合理的证明
开发应用程序和系统软件的成本
- 通常是任何可编程设备的主要约束条件
在不同时间和相同时间的不同应用中,这些因素的相对平衡可能导致广泛变化的架构选择。
早期的指令集
一般少于24个指令

单累加器机器

解释:
- LOOP: 加载N,即当前循环的计数器
- JGE DONE: 检查N是否>=0,如果是跳转DONE,结束
- ADD ONE:将1加到N
- STORE N: 存储更新后的N
- F1: LOAD A, 加载Ai。
- F1: ADD B,进行加法运算将A
自更改代码

处理器-内存通路瓶颈早期的解决方案
- 索引能力(Indexing capability): 在计算机早期,编程涉及大量的数据管理和地址计算操作。例如,当你需要遍历一个数组或访问数据结构中的元素时,必须明确指定每个元素的内存地址。这需要许多指令来计算和管理这些地址,这种操作称为“书目管理”(bookkeeping),索引功能有效地减少了处理器需要执行的书目管理指令
- 处理器的本地存储。减少加载和存储操作(数据在 CPU 和内存之间的传输)数量。通过在 CPU 中提供少量快速的本地存储单元,称为寄存器(通常是 8-16 个)
- 复杂指令(Complex Instructions)。提供更复杂和功能强大的单个指令,使得一个指令可以完成多步操作,从而减少了指令获取的数量。这提高了处理效率,因为 CPU 不需要频繁从内存中提取指令。
- 紧凑指令(Compact Instructions)。 紧凑指令通过隐含操作数的地址位,使得每条指令所需的比特数减少,从而降低了获取指令的成本。
索引寄存器
增加特殊寄存器来简化地址计算
修改现有的指令为
asmLOAD x, IX // AC <- M[x+(IX)] ADD x, IX // AC <- (AC) + M[x+(IX)]其中, M[...] 表示从内存中读取数据
AC是累加器
x是一个基地址
IX是索引寄存器
第一个指令意思是从内存地址x+IX处读取数据, 并加载到累加器中
第二个指令意思是从内存地址x+IX处读取数据, 并将该数据于累加器AC的当前值相加,存回AC
添加新的指令在操纵索引寄存器
JZi x, IX // if (IX) = 0 then PC <- x else IX <- (IX) + 1 LOADi x, IX // IX <- M[x] (截断以适应IX)PC是程序计数器(Program Counter),用于指示当前执行的指令地址。
第一指令意思是,如果IX为0,则将PC设置为x(跳转到地址x执行)。如果IX的值不为0,则将IX的值加1。 为什么可以简化控制流? 遍历数组时,如果IX为0,可以跳转到特定位置执行其他,否则继续遍历
第二条意思是,从内存地址x读取数据,将该数据加载到索引寄存器IX中。如果超出IX容量则截断。为什么可以简化控制流?这条指令允许动态地更新索引寄存器的值。例如,可以根据程序的需要动态地设置新的偏移量或基地址。
索引寄存器有累加器类似的特性。
至此,上述的Ci <- Ai + Bi, 0 <= i <= n,可以写成
LOADi N, IX
LOOP JZi DONE, IX
LOAD LASTA, IX
ADD LASTB, IX
STORE LASTC, IX
JUMP LOOP
DONE HALT
分析

引入索引寄存器代价
- 更加复杂的控制
- 索引寄存器的计算(需要类似ALU的电路)
- 指令需要多1-2个比特
在举个例子
// 给索引寄存器增加k
AC <- (IX)
AC <- (AC) + k
IX <- (AC)
// 累加器AC必须保存和重新加载
// 直接增加IX可能更好
INCi k, IX // IX <-(IX) + k
// 需要操作索引寄存器
STOREi x, IX // M[x] <- (IX) 需要适应一个字大小来索引一开始, IX看起来像个累加器, 后面引入多个索引寄存器和多个累加器,这样可以同时处理更多的数据和地址需求,再后来就索引寄存器和累加器的功能开始融合,就演变成了通用寄存器。
如何支持子例程调用

一个特殊的子例程跳转的指令
A: JSR F. //