CPU 是如何设计和制造的:计算机体系结构基础
快速阅读: 《技术点》消息,本文介绍了计算机中央处理器(CPU)及其工作原理,涵盖了计算机体系结构、指令集、缓存、流水线、超线程等内容。文章分四个部分详细介绍CPU的核心功能和设计过程,帮助读者理解计算机硬件的基础知识。欢迎关注后续章节,了解CPU内部构造和未来趋势。
我们通常把中央处理器(CPU)比作计算机的大脑,但这具体意味着什么呢?这具体意味着什么呢?在计算机内部,数十亿个晶体管是如何让你的计算机工作的?在这个四部分系列中,我们将专注于计算机硬件设计,探讨计算机运行的所有细节。本系列将涵盖计算机体系结构、处理器电路设计、超大规模集成电路(VLSI)、芯片制造以及计算领域的未来趋势。如果你一直对处理器内部的工作原理感兴趣,请继续关注——这是你需要掌握的基础知识。
第一部分:计算机体系结构基础(指令集架构、缓存、流水线、超线程)
第二部分:CPU设计过程(示意图、晶体管、逻辑门、时钟)
第三部分:布局和物理构建芯片(VLSI和硅片制造)
第四部分:当前趋势和计算机体系结构中的热点话题(加速器海洋、三维集成、FPGA、近内存计算)
CPU实际做什么?让我们从一个非常高的层面开始,看看处理器做了什么以及构建块如何在功能设计中结合在一起。这包括处理器核心、内存层次结构、分支预测等。首先,我们需要一个关于CPU基本功能的定义。CPU实际做什么?最简单的解释是,CPU按照一系列指令对一组输入执行某些操作。例如,这可能是从内存中读取一个值,将其加到另一个值上,然后将结果存储在内存的不同位置。它也可能是更复杂的事情,比如如果前一次计算的结果大于零,则除以两个数字。当你想运行像操作系统或游戏这样的程序时,该程序本身就是一系列供CPU执行的指令。这些指令从内存加载,并在一个简单的处理器上逐个执行,直到程序完成。虽然软件开发人员用像C++或Python这样的高级语言编写他们的程序,但处理器无法理解这一点。它只能理解1和0,所以我们需要一种方法来以这种格式表示代码。
CPU指令的基本知识
程序被编译成一组称为汇编语言的低级指令,作为指令集架构(ISAI)的一部分。这是CPU被构建出来理解和执行的一组指令。一些最常见的ISAI有x86、MIPS、ARM、RISC-V和PowerPC。就像在C++中写函数的语法与在Python中做同样事情的函数语法不同一样,每个ISAI都有自己的语法。这些ISAI可以分为两大类:固定长度和可变长度。RISC-V ISAI使用固定长度的指令,这意味着每条指令中预定义的一定数量的位决定了它是哪种类型的指令。这与x86不同,后者使用可变长度的指令。在x86中,指令可以用不同的方式编码,并且对于不同的部分可以使用不同数量的位。由于这种复杂性,x86 CPU中的指令解码器通常是整个设计中最复杂的部分。
程序被编译成一组称为汇编语言的低级指令,作为指令集架构(ISAI)的一部分。这是CPU被构建出来理解和执行的一组指令。一些最常见的ISAI有x86、MIPS、ARM、RISC-V和PowerPC。就像在C++中写函数的语法与在Python中做同样事情的函数语法不同一样,每个ISAI都有自己的语法。固定长度的指令由于其规则的结构而更容易解码,但限制了ISAI能够支持的指令总数。虽然常见的RISC-V架构版本大约有100条指令并且是开源的,但x86是专有的,没有人真正知道有多少指令存在。人们普遍认为有几千条x86指令,但确切的数量并不公开。尽管这些ISAI之间存在差异,但它们都具有本质上相同的内核功能。
以下是RISC-V指令的一些示例。右侧的操作码为7位,确定指令类型。每条指令还包含用于指定寄存器和执行哪些功能的位。这就是汇编指令如何被分解成二进制格式以便CPU理解。程序被编译成一组称为汇编语言的低级指令,作为指令集架构(ISAI)的一部分。这是CPU被构建出来理解和执行的一组指令。一些最常见的ISAI有x86、MIPS、ARM、RISC-V和PowerPC。就像在C++中写函数的语法与在Python中做同样事情的函数语法不同一样,每个ISAI都有自己的语法。
现在我们可以打开电脑并开始运行东西了。执行一条指令实际上有几个基本步骤,这些步骤贯穿于处理器的许多阶段。取指、译码、执行:CPU执行周期第一步是从内存中获取指令到CPU以开始执行。在第二步中,指令被译码,这样CPU就可以弄清楚它是什么类型的指令。有许多类型,包括算术指令、分支指令和内存指令。一旦CPU知道了它正在执行的是哪种类型的指令,就会从内存或CPU内部寄存器中收集指令的操作数。如果你想把数字A加到数字B上,你不能在不知道A和B的实际值之前进行加法运算。大多数现代处理器是64位的,这意味着每个数据值的大小为64位。取指、译码、执行:CPU执行周期64位指的是CPU寄存器、数据路径及/或内存地址的宽度。对于普通用户而言,这意味着计算机一次能处理多少信息,最好把它与较小的架构(如32位)进行比较。64位架构一次能处理两倍的信息量(64位对32位)。在CPU获取指令的操作数后,它会进入执行阶段,在输入上执行操作。这可能是加法运算,对数字进行逻辑操作,或者只是将数字通过而不进行修改。在结果计算出来之后,可能需要访问内存来存储结果,或者CPU可以直接将值保存在其中一个内部寄存器中。在结果存储之后,CP U将更新各种元素的状态并移动到下一条指令。当然,这个描述是一个巨大的简化,大多数现代处理器会将这几个阶段分解成20多个更小的阶段以提高效率。这意味着虽然处理器会在每个周期开始和结束几条指令,但任何一条指令从开始到结束可能需要20个或更多的周期。这种模型通常被称为流水线,因为它需要一段时间才能填满流水线,就像液体完全通过一样,但一旦流水线满了,你就能得到持续的输出。
4级流水线的示例。彩色框代表彼此独立的指令。图像来源:维基百科
乱序执行和超标量架构
指令经历的整个周期是一个非常紧密协调的过程,但并不是所有指令都能在同一时间完成。例如,加法非常快,而除法或从内存加载可能需要数百个周期。与其让整个处理器在一条慢指令完成之前停滞不前,大多数现代处理器执行乱序执行。这意味着它们会确定在给定时间执行哪条指令是最有益的,并缓冲其他未准备好的指令。如果当前指令尚未准备好,处理器可能会跳转到代码的前面查看是否有其他指令已经准备好。除了乱序执行外,典型的现代处理器采用所谓的超标量架构。这意味着在任何给定时间,处理器可以在每个流水线阶段同时执行多条指令。它也可能在等待数百条其他指令开始执行。为了同时执行多条指令,处理器内部会有多个流水线阶段的副本。如果处理器发现两条指令已准备好执行且它们之间没有依赖关系,那么它不会分别等待它们完成,而是会同时执行这两条指令。一种常见的实现方式叫做同时多线程(SMT),也称为超线程。英特尔和AMD处理器通常支持双向SMT,而IBM开发的芯片支持多达八向SMT。
除了乱序执行外,典型的现代处理器采用所谓的超标量架构。这意味着在任何给定时间,处理器可以在每个流水线阶段同时执行多条指令。它也可能在等待数百条其他指令开始执行。为了同时执行多条指令,处理器内部会有多个流水线阶段的副本。为了实现这种精心安排的执行,处理器除了基本核心之外还有许多额外的组件。处理器中有数百个单独的模块,每个模块都有特定的功能,但这里我们只介绍基本概念。最重要的两个是缓存和分支预测器。
除了乱序执行外,典型的现代处理器采用所谓的超标量架构。这意味着在任何给定时间,处理器可以在每个流水线阶段同时执行多条指令。它也可能在等待数百条其他指令开始执行。为了同时执行多条指令,处理器内部会有多个流水线阶段的副本。缓存的目的常常让人感到困惑,因为它们像RAM或SSD一样存储数据。即使RAM非常快,它相对于CPU来说仍然慢了好几个数量级。可能需要数百个周期RAM才能响应数据,处理器将陷入无所事事的状态。如果数据不在RAM中,从SSD访问数据可能需要数万次周期。如果没有缓存,我们的处理器将会停止工作。处理器通常有三级缓存,形成了所谓的内存层次结构。L1缓存是最小且最快的,L2位于中间,L3是最大且最慢的缓存。在缓存层次结构之上是一些小寄存器,它们在计算过程中存储单个数据值。这些寄存器是你系统中最快的存储设备,比其他设备快好几个数量级。当编译器将高级程序转换为汇编语言时,它会确定最佳的方式利用这些寄存器。当CPU请求数据时,它首先检查L1缓存中是否已有该数据。如果存在,数据可以在几个周期内快速访问。如果不存在, CPU会检查L2缓存,然后搜索L3缓存。缓存的实现方式通常是透明的,对核心而言是不可见的。核心只需请求指定内存地址的数据,哪个层级有数据就会响应。随着我们进入内存层次结构的后续阶段,大小和延迟通常会以数量级增长。最终,如果CPU在所有缓存中都找不到所需的数据,才会去主内存(RAM)查找。
处理器通常有三级缓存,形成了所谓的内存层次结构。L1缓存是最小且最快的,L2位于中间,L3是最大且最慢的缓存。在缓存层次结构之上是一些小寄存器,它们在计算过程中存储单个数据值。这些寄存器是你系统中最快的存储设备,比其他设备快好几个数量级。当编译器将高级程序转换为汇编语言时,它会确定最佳的方式利用这些寄存器。在典型的处理器中,每个核心会有两个L1缓存:一个用于数据,一个用于指令。L1缓存的总容量通常约为100KB,具体大小可能因芯片和代际而异。每个核心通常还会有一个L2缓存,但在某些架构中,它可能会在两个核心之间共享。L2缓存通常为几百KB。最后,有一个单个的L3缓存,由所有核心共享,容量约为几十MB。当处理器执行代码时,它最常使用的指令和数据值会被缓存起来。这显著提高了执行速度,因为处理器不需要不断从主内存获取所需的数据。我们将在本系列的第二部分和第三部分更详细地讨论这些内存系统是如何实现的。值得注意的是,虽然三级缓存层次结构(L1、L2、L3)仍然是标准配置,但现代CPU(例如AMD的Ryzen 3D V-Cache)已经开始采用额外的堆叠缓存层,这在某些情况下可以提升性能。
分支指令类似于处理器中的”如果”语句。如果条件为真,则执行一组指令;如果条件为假,则执行另一组指令。例如,你可能想比较两个数字,如果它们相等,则执行一个函数,如果不同,则执行另一个函数。这些分支指令非常常见,大约占程序中所有指令的20%。表面上看,这些分支指令可能看似不是问题,但实际上对于处理器来说正确处理它们是非常具有挑战性的。由于在任何时刻,CPU可能正在同时执行十个或二十个指令,因此知道哪些指令需要执行非常重要。确定当前指令是否为分支指令可能需要5个周期,而确定条件是否为真则可能需要另外10个周期。在这段时间里,CPU可能会开始执行数十个其他指令,甚至不知道这些指令是否为正确的指令。为了解决这个问题,所有现代高性能处理器都会使用一种称为推测的技术。这意味着处理器会跟踪分支指令并预测分支是否会执行。如果预测正确,处理器已经开始了后续指令的执行,从而提高了性能。如果预测错误,处理器会停止执行,丢弃所有错误执行的指令,并从正确的位置重新启动。推测执行技术是最早的机器学习形式之一,因为它随着时间适应分支行为。如果预测器做出了太多错误的猜测,它会调整以提高准确性。数十年的研究使现代处理器的分支预测精度超过了90%。尽管推测执行通过允许处理器执行准备好的指令而不是等待停滞的指令显著提升了性能,但它也引入了安全漏洞。臭名昭著的Spectre攻击利用了分支预测中的推测执行漏洞。攻击者可以使用特别设计的代码来诱使处理器推测性地执行会泄露敏感内存数据的指令。因此,为了防止数据泄露,一些推测执行的方面必须重新设计,导致性能略有下降。
现代处理器的架构在过去几十年中取得了巨大的进步。创新和巧妙的设计带来了更高的性能和更好的硬件资源利用率。然而,CPU制造商对其处理器内部的具体技术高度保密,因此无法确切了解其内部发生了什么。尽管如此,处理器的工作原理的基本原则在所有设计中保持一致。英特尔可能会添加秘密配方来提高缓存命中率,而AMD可能会添加高级分支预测器,但它们都实现了相同的目标。
第一部分:计算机体系结构基础(指令集架构、缓存、流水线、超线程)
第二部分:CPU设计过程(电路图、晶体管、逻辑门、时钟)
第三部分:布局和物理制造芯片(VLSI和硅片制造)
第四部分:计算机体系结构中的当前趋势和未来热点话题(加速器海洋、三维集成、FPGA、近内存计算)
本概述和系列的第一部分涵盖了处理器工作原理的大部分基础知识。在第二部分,我们将讨论构成CPU的组件是如何设计的,包括逻辑门、时钟、电源管理、电路图等。如果你喜欢我们的内容,请考虑订阅。无广告TechSpot体验,同时支持我们的工作。
我们的承诺:所有读者贡献将用于资助更多内容,这意味着:更多的技术特性、更多的基准测试和分析
(以上内容均由Ai生成)