咱们不拿“灵光一闪”当口号,咱们就聊聊计算机到底是如何把一坨原始数据变成你屏幕上的字的。 别听那些书里说“冯·诺依曼结构”那是多么神圣,那玩意儿在早期的 CPU 上确实像给大脑装了个外骨骼,连呼吸都得靠接口插着。但目前咱们得先明白点,CPU 本质上就是个高速运算的胖子,它肚子里塞着一堆寄存器、缓存和流水线,干活的时候就是不断吐数据、再吐结局。 想象一下,你输入一串数字,这时候 CPU 实际上早就去忙活了。它从内存里把数据掏出来,扔进寄存器里,然后启动分批次往里塞数据。
这一过程就像个工厂流水线,左手拿数据,右手算概率,左手又拿数据,右手管概率,忙得脚不沾地。
这个过程叫流水线执行,就是让 CPU 看起来像是与此同时在做十件事,实际上它只是在维持一种务必保持的繁忙状态。 那到底是如何算的?算法里全是加法、减法、乘法、除法和逻辑判断。CPU 靠的是指令集,它手里拿着几千种指令卡,每种卡在 CPU 上都有固定的位置,这叫寻址。指令的位置拍板了它是不是加法指令还是移位指令,这如何算是不是得看数据放在哪儿。
比如你要算个乘法,CPU 得先把两个数都搬进寄存器,然后指令管住器把“乘法”这个指令摆好,接着把第一个数送那会儿,把第二个数送过来。 这时候,CPU 并不是一口气做完的,它是分步跑的。
第一步,它读两个数;第二步,它执行加法;第三步,它读第三个数;第四步,执行减法。
这看起来挺像串行,但实际上是并行化的。流水线就是个多工处理系统,它把任务切成小块,每一块都跑在不同的“线程”上,一块在算加法,一块在算乘法,一块在解压数据,与此同时它们在跑。
这种并行加速让 CPU 的运算速度比单纯靠加法器堆出来的还要快,出于加法器根本没法与此同时做两件事。 内存这块儿往往让人头疼,出于数据存取慢。
要是一块数据在内存里,CPU 得给它找一次位置,还要读一次,再找个地方存结局,这得走好几条路。好办的算法有时候加上这些开销,跑得比蚂蚁还慢。
故此高性能 CPU 里,缓存起了大功能。它就是一个高速小内存,专门用来存立马要用到的数据。
要是数据在内存里,CPU 得先查缓存,查不到再去内存里翻,这就好比你要找一本书,先看书架上有没有,没有再翻到睡觉那屋里找。缓存离 CPU 特别近,并且小,故此命中率挺高,这样 CPU 就不用花工夫去读内存,直接拿来用。 数据在内存里存着,CPU 还得再读一遍,这时候 CPU 就会遇到一个难题:如何快速地把内存里的数据塞进寄存器?这叫内存到寄存器转换。一个好的 CPU 会有专门的路径和电路,专门负责这个转换,耗时极低。一旦数据进了寄存器,CPU 的运算单元就能直接操作它,效率就上去了。 那数据在寄存器里面又如何传呢?CPU 的寄存器也是分区的,有的管整数,有的管浮点,有的管地址。数据如何从一个寄存器跳到另一个寄存器?这叫寄存器间搬运。
要是两个寄存器离得近,CPU 就能够直接借引脚把数据从 A 传到 B,这就像邻居之间提个东西,不用走公共通道。但要是两个寄存器隔得忒远,CPU 就得先把数据存到缓存要么内存里,再去拿回来再转,这时候 CPU 就得停下来等数据回来,这就叫停顿。为了削减停顿,现代 CPU 设计了大量延迟线,让数据能在寄存器里转好几个周期,这样 CPU 就能够持续干活,直到数据真正从内存要么缓存里取完为止。 最终,还得说说硬件如何拍板算得快不快。CPU 的运算单元本身是串并行结合的,它内部就有多个功能单元与此同时工作,这比纯串行的要快。并且,随着摩尔定律,晶体管密度越来越高,晶体管之间距离越近,电子移动的路径就越短,信号传输就越快。
这就好比让一个高速打印机打印得比一个慢速打印机快,出于墨水跑得快,打印机也能做得快。 有时候,硬件和算法的匹配也挺关键。有些算法在硬件上跑得特别快,比如卷积运算,出于卷积算法天生就有并行性,能够在一个单元里就搞定大量数据的相关性计算,而不需求把数据一个个传那会儿。而要是是复杂的矩阵运算,数据量忒大,可能得用到多核 CPU 要么 GPU 这种特殊的硬件,专门负责处理这些大块数据。 说到底,计算机运算的原理忒复杂,涉及到底层电路、信号整个性、时钟频率、缓存层级、流水线设计这些东西。它们看起来像是在玩高科技游戏,实际上都是为了让数据更快、更准地到达你的屏幕。
没有这些基础,就没有我们目前的任何软件体验。