try ai
科普
编辑
分享
反馈
  • 冯·诺依曼架构

冯·诺依曼架构

SciencePedia玻尔百科
核心要点
  • 冯·诺依曼架构通过其存储程序概念定义了现代计算机,将指令和数据存储在单一、统一的内存中。
  • 其主要局限性是“冯·诺依曼瓶颈”,即CPU和内存之间的共享总线成为一个关键的性能瓶颈。
  • 现代CPU采用混合设计,使用分离的指令和数据缓存,以获得类哈佛架构的速度,同时保留统一内存系统的灵活性。
  • 此架构在人工智能等领域的局限性正在推动新的计算范式,如受人脑效率启发的内存中处理和神经形态计算。

引言

75年来,一个简洁而优雅的原则几乎成为了所有数字设备的蓝图,从你口袋里的智能手机到模拟我们气候的超级计算机。这个原则就是冯·诺依曼架构,一个如此基础的设计,其影响力无处不在,却又常常不为人所见。虽然其存储程序概念通过将专用机器转变为通用工具,彻底改变了计算领域,但它也引入了一个关键的局限性——一个固有的交通拥堵问题,工程师和科学家们自此一直在努力解决。本文深入探讨这一基础架构,旨在弥合其简洁优雅与复杂深远影响之间的差距。

我们首先将在“原理与机制”一节中剖析该设计的核心信条,探讨计算机如何从统一内存中获取并执行指令,以及为何这会导致臭名昭著的“冯·诺依曼瓶颈”。接着,“应用与跨学科联系”一节将揭示这一架构选择如何深刻影响从高性能计算和人工智能到机器人学乃至合成生物学等不同领域。读完本文,你将不仅理解计算机是如何工作的,还将明白为何其设计本身正推动我们走向计算的新前沿。

原理与机制

想象一下,你是一位身处巨大厨房中的大厨。你的指令并非写在另一本食谱上;相反,你的配方就写在食材的罐子上。要烤一个蛋糕,你首先找到标有“面粉”的罐子,阅读写在上面的第一步配方,然后取来“糖”罐,阅读下一步,依此类推。这种奇特的厨房组织方式,本质上就是你用过的几乎每一台计算机背后的那个深刻而简单的思想。它就是​​冯·诺e依曼架构​​的核心。

革命性思想:单一、通用的内存

在 John von Neumann 和他的同代人在1940年代提出这一蓝图之前,计算机都是“专家”。它们的指令是硬连线的,就像一个只能播放一首曲子的音乐盒。要更改程序,你必须物理上重新布线。而那个伟大的概念飞跃就是​​存储程序概念​​:计算机遵循的程序——即指令——与它操作的数据并无本质区别。两者可以一同存储在同一个内存中。

这意味着计算机的内存就像一个巨大、统一的草稿板。这个板上的一些单元格存着数字,一些存着文本,另一些则存着告诉计算机如何处理这些数字和文本的指令。这带来了一个惊人的结果:计算机可以像处理任何其他数据一样轻松地处理自己的指令。这使得计算机从一个固定功能的计算器变成了一台通用机器。正是因为这个原因,单一设备可以这一刻是文字处理器,下一刻是游戏机,再之后是科学模拟器。编写一个程序(如编译器)来编写其他程序的能力,正是这一优雅思想的直接产物。

这甚至允许所谓的​​自修改代码​​,即程序在运行时主动重写自己的指令。尽管在现代软件中这种做法罕见且复杂,但其可能性证明了将代码和数据视为一体的强大威力。

取指与执行之舞

那么这实际上是如何工作的呢?让我们深入了解一下。计算机的两个主要组件是中央处理器(​​CPU​​),即“厨师”,以及主内存,即存放指令和数据的“储藏室”。它们通过一条单一的路径或​​总线​​连接——一种狭窄的走廊。

CPU采取的每一个动作都始于获取一条指令。CPU内部有一个特殊的计数器,即程序计数器(​​PC​​),它保存着下一条要执行的指令的内存地址。这个过程,是一场精心编排的电子信号之舞,大致如下:

  1. ​​取指(Fetch)​​:

    • CPU将PC中的地址放入内存地址寄存器(MAR),实际上是在“拨号”到内存中的正确位置。
    • 它通过总线发送一个‘读’信号。
    • 内存响应,将该地址的内容——指令字——放入内存数据寄存器(MDR)。
    • CPU将此指令从MDR复制到其指令寄存器(IR)中进行解码。然后,PC自增以指向下一条指令。
  2. ​​执行(Execute)​​:现在,CPU解码指令。如果指令是,比如说,LOAD R_d, [R_s](从一个内存位置加载一个值到寄存器中),这场舞继续进行:

    • CPU取出存储在寄存器R_s中的地址,并将其放入MAR。
    • 它通过总线发送另一个‘读’信号。
    • 内存将被请求的数据字放入MDR。
    • 最后,CPU将数据从MDR复制到目标寄存器R_d。

注意到这个模式了吗?为了执行一条涉及内存数据的单一指令,CPU必须使用那条唯一的总线两次:一次用于取指,第二次用于取数据。症结就在于此。

不可避免的交通拥堵:冯·诺依曼瓶颈

单一、统一内存的优雅是有代价的。连接CPU和内存的单一总线成为了一个瓶颈。CPU可能每秒能够执行数十亿次操作,但它必须不断等待指令和数据在这条狭窄的路径上来回穿梭。这种交通拥堵就是著名的​​冯·诺依曼瓶颈​​。

我们可以在一个简单的反馈控制循环中清楚地看到这一点。一次循环迭代的总时间 tloopt_{\text{loop}}tloop​,从根本上受到一系列串行任务的限制:取指令所花费的时间(tIFt_{IF}tIF​)、访问内存数据所花费的时间(tMEMt_{MEM}tMEM​)以及纯计算所花费的时间(tEXt_{EX}tEX​)。因为它们都竞争相同的资源(用于取指和数据访问的总线,然后是用于执行的CPU),所以最短时间是它们的总和:

tloop=tIF+tMEM+tEXt_{\text{loop}} = t_{IF} + t_{MEM} + t_{EX}tloop​=tIF​+tMEM​+tEX​

这些活动之间没有重叠;它们必须一个接一个地发生。

让我们把这一点变得更具体。想象一个简单的循环,它将一个常数加到数组的每个元素上:for i = 0 to N-1: A[i] := A[i] + c。对于每个元素,CPU必须:

  1. 从内存中读取A[i]的当前值(1次数据访问)。
  2. 将新值写回内存中的A[i](1次数据访问)。

这是两次数据传输。但是告诉CPU做这些事的指令呢?假设循环体由 mmm 条指令组成(加载、相加、存储、更新索引、分支)。由于这些指令也存在于同一个内存中,它们也必须通过同一条总线来获取。因此,对于我们处理的数组中的每一个元素,我们有 mmm 次指令提取和 222 次数据传输。每个元素的总内存流量是 m+2m+2m+2 次事务。在这部分流量中,比例为 mm+2\frac{m}{m+2}m+2m​ 的部分仅用于获取指令!如果 m=4m=4m=4,那么三分之二的内存带宽被仅仅用于告诉CPU该做什么,只留下三分之一用于它本应处理的实际数据。这就是瓶颈在起作用。

架构的另一条路:哈佛解决方案

如果一条走廊太慢,显而易见的解决方案是建造第二条。这正是​​哈佛架构​​背后的思想。它有两个物理上独立的内存,各自拥有专用的总线:一个用于指令,一个用于数据。现在,CPU可以在访问当前指令所需数据的同时,获取下一条指令。

性能提升是显著的。如果一个循环需要 fff 次指令提取和 lll 次数据加载,冯·诺依曼机器所需的时间与 f+lf+lf+l 成正比。而哈佛机器,因为并行执行两者,所需的时间与 max⁡(f,l)\max(f, l)max(f,l) 成正比。因此,吞吐量增益 GGG 为:

G=f+lmax⁡(f,l)G = \frac{f+l}{\max(f, l)}G=max(f,l)f+l​

如果 fff 和 lll 相等,哈佛机器的速度几乎是前者的两倍。

那么为什么不是每台计算机都是纯粹的哈佛机器呢?因为灵活性。冯·诺依曼机器的统一内存通用性极好;内存可以根据需要动态地分配给代码或数据。现代处理器巧妙地采用了一种混合方法。在最高层级上,它们是具有单一主内存的冯·诺依曼机器。但更靠近CPU的地方,它们采用了​​分离式缓存​​——小而快的临时存储区域——一个用于指令的独立缓存(I-cache)和一个用于数据的缓存(D-cache)。这使它们在最频繁的操作中拥有了哈佛架构的并行访问速度,同时保留了统一内存系统的整体灵活性。

与极限共存:性能的屋顶线

尽管有缓存等巧妙的技巧,由数据移动施加的根本限制依然存在。在高性能计算中,​​Roofline模型​​完美地捕捉了这一点。想象一个图表,其中纵轴是计算性能(以每秒操作次数为单位),横轴是程序的​​运算强度​​——算术运算与从内存移动的数据字节数之比。

该模型显示,处理器的性能受到两个“屋顶”的制约:

  1. ​​计算屋顶(PpeakP_{\text{peak}}Ppeak​)​​:一条平坦的水平线,代表处理器的最大理论速度。这是在数据能神奇地立即可用的情况下,CPU 能够 达到的运行速度。
  2. ​​内存屋顶(BW⋅IopBW \cdot I_{\text{op}}BW⋅Iop​)​​:一条斜线,代表内存带宽(BWBWBW)施加的限制。在这条斜线上可达到的性能是内存带宽乘以运算强度(IopI_{\text{op}}Iop​)。

实际性能 PPP 被这两个屋顶中较低的一个所限制:

P≤min⁡(Ppeak,BW⋅Iop)P \le \min(P_{\text{peak}}, BW \cdot I_{\text{op}})P≤min(Ppeak​,BW⋅Iop​)

如果一个程序的运算强度低(它为获取的每个字节执行很少的计算,即“内存受限”任务),其性能就会被困在屋顶的斜坡部分,完全由内存带宽决定。只有运算强度非常高的程序(“计算受限”任务)才能突破内存屋顶,达到处理器的峰值性能。冯·诺依曼瓶颈不再只是一个概念;它是一个对性能的硬性、量化的上限。

机器中的幽灵:意想不到的后果

冯·诺依曼架构为通用计算提供了基础,其能力等同于理论上的图灵机——它可以计算任何可计算的东西。它相对于图灵机的主要优势是​​随机访问​​,即能够一步跳转到任何内存位置,而不是顺序遍历一条带子。这正是现实中的计算机如此惊人快速的原因。然而,其核心思想的优雅简洁也创造了深刻且有时令人惊讶的复杂性。

再考虑一下自修改代码。在具有分离式缓存的现代混合处理器上,如果CPU向内存写入一条新指令,这个更改会进入D-cache。但是,将要获取该指令的I-cache对此一无所知!新指令在错误的缓存中。为了使之正常工作,程序员必须执行一个精细的、多步骤的仪式:强制将更改从存储缓冲区写入D-cache,将更改从D-cache刷写到主内存,显式地使I-cache中的旧指令失效,最后,清空处理器的流水线,以确保它不会执行一个过时的、推测性获取的副本。一个简单的概念导致了一个复杂的现实。

更令人震惊的是,这种架构如何导致安全漏洞。​​推测执行​​(CPU为了节省时间而猜测接下来要执行哪些指令)和统一缓存的组合可以被利用。在像Spectre这样的攻击中,攻击者可以诱使CPU推测性地访问一个秘密数据值。这个推测性访问从未在架构上提交,但它会留下一个微架构痕迹。例如,这个推测性的数据加载可能会从统一缓存中驱逐一个特定的行。然后,攻击者计时获取一个映射到同一缓存行的指令需要多长时间。如果获取速度很慢(缓存未命中),攻击者就知道该行被驱逐了,这揭示了关于依赖于秘密数据的推测性访问的信息。

这是一个惊人的转折。一次数据访问影响了一次指令提取。一个被扼杀的、从未发生的计算的幽灵,通过共享资源的时序侧信道效应泄露了真实信息。单一内存的简单、优美的思想,作为现代计算的根基,却在代码和数据之间创造了一种微妙的联系,这种联系可以被以其创造者从未想象过的方式加以利用。这是一个强有力的提醒:在科学和工程中,最优雅的原则也可能带来最深刻和最意想不到的后果。

应用与跨学科联系

在窥探了冯·诺依曼架构优雅的内部机制——存储程序概念、统一内存——之后,我们可能会想把它当作工程史上已解决的一章而束之高阁。但这样做就完全错过了重点。这个架构不是博物馆里的静态蓝图;它是一个活生生的原则,其影响,无论是辉煌的还是充满挑战的,都回响在我们技术世界的几乎每一个方面,甚至渗透到生命本身的基本逻辑中。它是一面透镜,通过它,我们不仅可以理解计算机如何工作,还能理解它们为何以这种方式工作,以及计算的未来可能是什么样子。

机器中的幽灵:代码即数据

冯·诺依曼架构最深刻、最直接的后果是指令即数据这一思想。这不仅仅是一个巧妙的技巧;它是使现代软件成为可能的基础魔法。想一想任何程序中最常见的操作之一:调用子程序或函数。程序必须跳转到一个新位置来执行函数,但它也需要记住如何返回。它是如何做到的呢?它获取返回地址——一个代表代码中某个位置的数字——并像保存任何其他数据一样将其保存在内存中。每当你的代码进行一次函数调用时,一小段“代码”就变成了“数据”,被推入调用栈;每一次返回又将其弹出,变回“代码”。这种在指令和信息之间的持续、无缝的转换是如此基础,以至于我们几乎注意不到它,然而这些操作中的每一个都消耗着真实的资源,在共享的内存总线上占据短暂的瞬间。

这一原则在元编程世界中得到了最壮观的体现,即程序编写其他程序。考虑一下运行Java、JavaScript或Python等语言的高性能虚拟机。为了加速,它们通常使用即时(JIT)编译器。这个编译器在代码运行时进行观察,并动态地将频繁使用的部分翻译成高效的机器码。它实际上是将新的指令——新的代码——像简单数据一样写入内存。然后,只需轻轻切换,处理器就被告知去执行这段新生成的代码。这是冯·诺依曼架构最动态的形式:一个可以在运行时改进和重写自身的系统。当然,这种能力也带来了其自身的复杂性。在具有复杂缓存的现代处理器中,系统必须执行一场小心翼翼的舞蹈,包括刷新数据缓存和使指令缓存失效,以确保刚刚写入的“数据”能被处理器正确地视为可执行的“代码”——这是一个直接源于内存统一性的迷人挑战。

大交通拥堵:冯·诺依曼瓶颈

尽管其设计优雅,但统一架构有一个著名的阿喀琉斯之踵:处理器和内存之间的共享路径。因为所有指令和所有数据都必须沿这条单一的道路行进,它可能成为一个拥堵的瓶颈。这就是臭名昭著的“冯·诺依曼瓶颈”。想象一个能够以闪电般速度组装产品的出色工厂(处理器),但它与其仓库(内存)之间只有一条狭窄的乡间小路相连。无论工厂工作得多快,其总产出都受限于它获取零件和运送成品的速率。

这个瓶颈是高性能科学计算中的一个主导因素。在气候建模、天体物理学或材料科学等领域,我们经常对海量数据执行相对简单的计算。为了加速这一过程,处理器使用向量单元(SIMD),可以一次对多个数据点执行相同的操作。考虑一个简单的操作,如在包含数百万个元素的数组上执行 Ai=Bi+c⋅CiA_i = B_i + c \cdot C_iAi​=Bi​+c⋅Ci​。使用宽向量单元,一条指令可能加载、处理并存储数十个数字。结果,总线流量绝大部分被数据移动所主导——即数组 AAA、BBB 和 CCC。获取指令本身的流量相比之下变得几乎可以忽略不计。瓶颈完全转移到了数据移动上,这是共享总线的直接后果,也是推动处理器和内存系统设计演进的主要驱动力。

这种交通拥堵不仅仅是原始速度的问题;在某些领域,它关乎安全和稳定。考虑一个复杂机器人的控制器。在每个控制循环中(每秒发生数千次),处理器必须为其逻辑获取指令,从传感器(如关节角度、摄像头图像)读取数据,并向执行器(马达)发送命令。所有这些流量——代码、输入数据和输出数据——都必须在同一条内存总线上争夺时间。如果总线时间的总需求超过其容量,控制循环就无法足够快地执行。仅仅几微秒的延迟就可能导致不稳定,使机器人振荡或失控。抽象的架构瓶颈变成了一个具体的物理约束,限制了一个真实世界信息物理系统的最大安全运行频率[@problem-id:3688042]。

打破常规:当冯·诺依曼不再足够

像机器人控制器这样的实时系统的需求揭示了一个关键点:冯·诺依曼架构虽然强大,但并非万能的解决方案。其设计本身,特别是当为了提高平均性能而增加了缓存和操作系统等复杂功能时,引入了一定程度的时序不可预测性。对于那些错过截止期限即是灾难的应用——一个被称为硬实时系统的领域——这种不可预测性是不可接受的。

这导致了计算机架构中一个有趣的分化。虽然我们台式机和服务器中的通用微处理器(MPU)通常遵循冯·诺依曼模型,但许多专用设备却并非如此。微控制器(MCU)和数字信号处理器(DSP)——从引擎控制单元到音频设备无处不在——常常采用哈佛架构,它为指令和数据使用物理上独立的内存和总线。这种分离防止了数据密集型操作干扰指令获取,从而带来更可预测的时序。对于最严格的时序要求,例如在中描述的具有亚微秒级抖动约束的高频电机控制循环,设计者可能会完全放弃基于处理器的架构。取而代之,他们使用现场可编程门阵列(FPGA)将计算逻辑直接在硬件中实现为一个定制数字电路。在FPGA中,数据路径是一个物理流水线,其执行时间是固定的时钟周期数——提供了终极的时序确定性。这表明,计算领域是一个丰富的设计生态系统,每种设计都适应其特定的应用场景,“最佳”架构是灵活性、成本、平均性能和最坏情况可预测性之间权衡的结果。

内存墙与人工智能的黎明

近年来,冯·诺依曼瓶颈在大规模数据处理的背景下变得如此严重,以至于通常被称为“内存墙”。在人工智能领域,这堵墙比任何地方都更加明显。训练一个现代深度学习模型涉及根据庞大的数据集调整数十亿个参数或“权重”。在传统的冯·诺依曼机器中,这意味着处理器必须不断地从主内存(DRAM)中获取这些权重,执行一次小的计算,然后将更新后的权重写回。

如第一性原理和简单的能量模型所示,将一个数字从DRAM移动到处理器所需的能量和时间,可能比对其执行一次浮点运算所需的能量和时间高出几个数量级。结果是一种悲喜剧般的局面:我们那些功能强大到惊人、每秒能执行万亿次操作的处理器,却将绝大部分时间和能量花在仅仅等待数据到达上。对于这些工作负载,系统是严重内存受限的。这种极度的低效率直接违反了“状态共置原则”,即一个直观的想法:计算应该在它所修改的数据附近发生。

这个挑战是如此根本,以至于它正在激发对冯·诺依曼范式的彻底反思。如果将数据移动到处理器是问题所在,为什么不将处理器移动到数据那里呢?这就是​​内存中计算​​或​​存内计算(PIM)​​的核心思想。这些新兴技术旨在将计算能力直接嵌入到内存阵列中。它们不是将数字取到ALU,而是在原地执行乘法和累加等基本操作,利用内存单元本身的物理特性,从而从源头上缓解数据移动瓶颈。这代表了计算机架构中最令人兴奋的前沿之一,其驱动力正是一个为我们服务了75年之久模型的局限性。

生命的回响:从大脑到生物学

寻求超越冯·诺依曼的架构,不仅引导我们走向巧妙的新芯片设计,还引导我们在我们所知的最强大、最高效的计算机中寻找灵感:人脑。​​神经形态计算​​试图构建基于神经生物学原理的系统,这些原理与冯·诺依曼模型形成鲜明对比。

传统计算机是同步的,由全局时钟的无情滴答声驱动,而大脑则是异步和事件驱动的。神经元仅在有信息需要传达时才会放电。冯·诺依曼机器将内存和计算分离,而在大脑中,内存(突触连接的强度)与计算(神经元中信号的整合)从根本上是共置的。这种事件驱动、共置的架构非常节能。如量化模型所示,对于具有稀疏活动的工作负载——例如处理真实世界的感官数据——与暴力破解的冯·诺依曼实现相比,神经形态方法可能将数据移动能耗降低数十万倍。它通过仅在需要时和需要的地方做功来实现这一点,这与每个时钟周期都在消耗能量的传统处理器形成了鲜明对比。

这就把我们带到了最后一个,也许是最深刻的联系。冯·诺依曼架构的核心概念呼应了生命本身的基本原则。在1940年代,John von Neumann 探索了一个​​自复制自动机​​的抽象逻辑。他构想了一台机器,由一个描述(“指令带”)、一个可以根据描述构建任何东西的通用构造器,以及一个管理过程的控制器组成。为了使机器能够复制,它需要使用构造器来构建一台新机器,然后复制自己的指令带给新机器。

这个抽象模型,以其“指令带”与“构造器”的关键分离,是对生物复制逻辑的一次惊人理论预测,比DNA和核糖体的作用被理解早了几十年。DNA分子就是指令带。核糖体和细胞更广泛的转录和翻译机制是通用构造器,解释DNA的指令来构建蛋白质,而蛋白质又构成新的细胞。​​合成生物学​​领域,在某种意义上,正是这一架构原则的直接应用。通过创造标准化的遗传部件和正交表达系统,科学家们正在通过设计新的“指令带”(工程化的DNA)在细胞预先存在的“构造器”上运行,来工程化新的生物功能。

至此,我们的旅程画上了一个圆满的句号。冯·诺依曼架构不仅仅是构建计算机的一种方式。它是对信息和复制结构的深刻洞察,一个由自然通过进化发现并由人类通过逻辑重新发现的原则。它驱动了数字革命,但其固有的局限性现在正迫使我们在新的地方寻找灵感——即便其核心概念帮助我们理解和改造生命本身。这个架构的故事就是现代计算的故事,一个关于优雅思想、其实际后果以及对未来的无尽探索的传说。