ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

计算机系统基本组成详解:从冯诺依曼体系到CPU与存储层次

计算机系统基本组成详解:从冯诺依曼体系到CPU与存储层次 如果你跟着这个系列一路读到这里那前面十几篇文章里那些二进制运算、逻辑门电路、甚至CPU流水线的底层细节其实都在为今天这篇做铺垫。这一篇要解决的是计算机系统基础里最基础、也最容易被人跳过的问题一台计算机到底由什么组成这些组成部件各自在干什么为什么冯·诺依曼体系结构能统治大半个世纪不管你是计算机专业刚入学的学生还是半路转行想补基础知识的开发者搞清楚这套基本组成和基本概念后面学操作系统、学组成原理、学编译原理都会轻松一大截。很多人觉得基本组成不就是看张结构图记住五大部件就完事了但实际面试、笔试、甚至工作中排查问题真正卡住人的往往不是那些高大上的算法而是这些基础概念之间的逻辑关系。比如内存和硬盘有什么区别为什么CPU要分寄存器、缓存、内存三级总线带宽和CPU主频哪个更影响性能。这篇就用最直白的大白话把计算机硬件的基本组成这套体系掰开揉碎讲清楚。1. 先站在高处看计算机系统1.1 为什么说计算机是硬件软件的组合严格意义上讲一台能正常工作的计算机系统除了你眼睛能看到的主机、屏幕、键盘鼠标这些硬件设备之外还必须有软件系统配合。硬件是计算机的物理实体是看得见摸得着的部分软件则是存储在硬件中的指令和数据是让硬件动起来的灵魂。你按一下电源键硬件通电开始工作但具体是先启动BIOS还是直接读硬盘全靠存储在只读存储器里的那段引导程序说了算。这里有个特别容易混淆的点大家平时张口闭口我的电脑配置是i7、16G内存、1T硬盘这些说的全是硬件但当你运行Word、浏览器、或者自己写的Python脚本时真正干活的是CPU而CPU执行的每一条机器指令本质上都是软件的一部分。硬件和软件之间不是简单的主次关系而是协作关系没有软件的硬件就是一块废铁没有硬件的软件就是一堆无意义的符号。从计算机系统基础的角度看分清楚硬件和软件的分界线在哪里比死记硬背部件清单重要得多。比如固件BIOS/UEFI这个东西它本身是软件但被固化在硬件芯片里所以属于介于两者之间的特殊存在。再比如指令集架构ISA它是硬件和软件之间的契约——硬件保证能执行这些指令软件保证只发这些指令。理解了这个层次你以后再看到RISC和CISC之争、ARM和x86的区别就不会觉得那是纯硬件或纯软件问题而是软硬件接口层面的问题。1.2 冯·诺依曼体系一切现代计算机的共同祖先聊计算机的基本组成绕不开冯·诺依曼和他提出的存储程序思想。1945年冯·诺依曼在参与EDVAC计算机设计时发表了一份报告提出了一个划时代的设计理念让指令和数据一样都以二进制形式存储在存储器中然后由控制器自动从存储器中取出指令、执行指令。在此之前计算机执行任务要靠人工插拔线路来编程而存储程序让计算机能自动、连续地执行预存的指令序列。这套体系结构定义了计算机硬件的五大基本部件运算器、控制器、存储器、输入设备、输出设备。你可能已经听过无数遍但我还是想强调一个大家容易忽略的点这五个部件到今天依然没有本质变化。你手里的智能手机、家里的路由器、汽车的ECU甚至一颗几块钱的MCU单片机内部都是这套结构。区别只是集成度更高、性能更强但骨架没变。为什么冯·诺依曼体系能统治这么久核心原因是指令和数据统一存储这个设计极其优雅——你不需要两套完全独立的存储系统一套存指令、一套存数据编译器生成的可执行文件可以一次性加载到内存里然后CPU从头到尾取指执行。虽然现代CPU在内部做了大量并行化改造比如指令流水线、多发射、乱序执行但从逻辑结构上看依然是取出指令→解析指令→执行指令这个循环。这个为什么想明白了后面学习指令流水线、分支预测这些高级话题时就不容易懵。2. 硬件五大部件的角色分工2.1 运算器和控制器CPU里的左右手运算器和控制器合在一起就是我们常说的中央处理器CPU。运算器负责执行算术运算加法、减法、乘除和逻辑运算与、或、非、比较大小控制器负责指挥协调——它从存储器取指令分析这条指令要做什么然后向各个部件发出控制信号让运算器去算、让存储器去读、让输入输出设备去传输数据。打个比方控制器像公司里的项目经理他自己不写代码但负责拆解需求、分配任务、检查进度运算器像开发工程师接到任务就埋头干活。没有项目经理工程师不知道该干嘛没有工程师项目经理再怎么派活儿也无人执行。现代CPU里运算器的核心是算术逻辑单元ALU它内部由全加器、移位器、逻辑门电路组成。在前面的系列文章里我们已经聊过如何用与门、或门、异或门构造出加法器ALU就是把这一大堆门电路整合封装起来的结果。控制器则包含程序计数器PC、指令寄存器IR和译码逻辑。PC保存着下一条要执行指令的内存地址IR暂存当前取出来的指令译码逻辑负责把二进制指令翻译成控制信号。理解这几个寄存器的职责对后面学汇编语言尤其重要——因为汇编里的jmp、call、ret指令本质上就是在改PC的值。2.2 存储器计算机的记忆中枢存储器的作用是保存指令和数据。按与CPU的物理距离和访问速度存储器可以分成寄存器在CPU内部、高速缓存Cache在CPU内部或紧邻CPU、主存内存条、外存硬盘、SSD、U盘。越靠近CPU的存储器速度越快、容量越小、价格越贵越远离CPU的存储器速度越慢、容量越大、价格越便宜。为什么需要这么多层存储器根本原因是速度匹配问题。CPU的执行速度以纳秒计而硬盘的访问速度以毫秒计差了百万倍。如果不做缓存CPU大部分时间都在干等数据性能会被严重拖累。所以现代计算机采用金字塔状的存储层次结构来平衡速度与成本。这里面有个特别重要的基本概念寄存器是CPU内部的存储单元它直接参与运算比如累加器保存当前运算结果地址寄存器保存访存地址。每个寄存器只有几十比特但访问速度与CPU主频同步。高速缓存分L1、L2、L3三级L1最快但容量只有几十KBL3稍慢但可能有几十MB。内存承担着运行程序的全部指令和数据的存放工作程序只有被加载到内存里CPU才能直接访问。而外存负责长期保存数据断电不丢失。2.3 输入输出设备人机对话的窗口输入设备把外部信息变成计算机能识别的二进制数据比如键盘、鼠标、麦克风、摄像头、传感器输出设备把计算机处理后的二进制结果转换成人能理解的形式比如显示器、打印机、音箱。输入输出的本质是格式转换——把人的信息编码成机器码再把机器码解码成人能感知的信息。初学者最容易忽略的是输入输出不只是接个外设这么简单。计算机系统基础要求你理解I/O设备与主机之间的数据传递方式主要有程序查询方式、中断方式、直接存储器访问DMA方式三种。程序查询方式最笨——CPU不停轮询设备状态浪费大量算力中断方式改进了一些——设备准备好后主动通知CPUCPU再处理DMA方式最聪明——数据在外设和内存之间直接传输CPU只需要在开始和结束时介入适用于硬盘读写、网卡收发数据这些大块数据传输场景。这块概念在操作系统课程里会反复出现比如系统调用中的read/write最终都会落到驱动程序和设备控制器上。能在基本组成阶段就把中断和DMA的概念建立起来之后学习Linux驱动就不会觉得陌生。3. 存储层次与数据流动3.1 为什么存储器要分层很多人第一次听到寄存器→缓存→内存→外存这个层次结构时都会问既然寄存器最快那为什么不把所有存储都做成寄存器答案很简单贵而且功耗高。静态存储器的每一个比特需要6个晶体管来保存256MB的SRAM就要几十亿个晶体管成本高到离谱。而动态存储器DRAM用一个晶体管加一个电容就能存一个比特密度高、成本低但速度远不如SRAM。于是计算机科学家们想出了一个聪明的折中方案不追求一种存储器解决所有问题而是用不同速度、不同成本的存储器组成一个协同工作的层次。这个设计的理论基石是局部性原理程序在短时间内倾向于访问同一组数据时间局部性而且倾向于访问相邻地址的数据空间局部性。因为局部性原理的存在缓存只需存放你最可能访问的那一小部分数据命中率就能达到95%以上。说白了存储分层就是给数据按冷热程度分类正在热用的数据放在寄存器很常用的放Cache常用的放内存几乎不用的长期数据放硬盘。操作系统的页面调度算法、数据库的缓冲池设计都借鉴了这套分层缓存的思想。3.2 寄存器和缓存是如何工作的寄存器的核心特征是与CPU同频工作任何运算都必须先把操作数从内存搬到寄存器运算结果也存放在寄存器里。x86架构里经典的寄存器有EAX、EBX、ECX、EDXARM架构里有R0~R15。编译器的作用之一就是决定哪些变量放寄存器、哪些变量放内存这个过程叫寄存器分配。一个变量如果能在寄存器里待着运算速度会比从内存加载快好几十倍所以编译器优化时总会尽量让热点变量寄存器化。高速缓存的运作方式可以理解为CPU请求数据时先看Cache里有没有有就是命中直接返回代价是几个时钟周期没有就是未命中必须去内存中读取代价是几百个时钟周期。Cache的映射方式有直接映射、组相联映射、全相联映射替换策略有LRU、LFU等。这些细节在计算机组成原理里会深入讲这里只需要记住两个核心指标命中率和未命中惩罚。命中率越高越好未命中惩罚越低越好设计缓存就是在这两者之间找平衡。这几年CPU中的缓存设计越来越复杂比如Intel的L3缓存做到了32MBAMD的3D V-Cache甚至堆到了96MB。表面上看这是容量竞赛但本质还是为了提升命中率、减少CPU等待内存的时间。3.3 内存与外存的分工内存主存和外存硬盘、SSD最本质的区别有三个工作方式不同、速度不同、断电后数据是否保留。内存按字节随机访问速度以纳秒计断电即失外存按块扇区访问SSD块大小通常是4KB机械硬盘扇区大小传统是512B速度以毫秒或微秒计断电后数据依然存在。因为外存是按块访问且速度慢操作系统在读取文件时不会一个字节一个字节去读而是成块地读入内存。你还记得虚拟内存这个概念吗它就是让程序以为拥有比物理内存更大的地址空间把暂时不用的数据页换到外存上要用时再换回内存。理解内存与外存的分工之后虚拟内存的原理就变得顺理成章了内存是CPU直接面对的活页夹外存是仓库。实操中判断卡顿是内存还是硬盘造成的最简单的观察方法就是打开任务管理器或资源监视器看看是内存占用率持续98%以上还是磁盘活动时间100%几乎不落。前者是内存瓶颈后者可能是硬盘速度瓶颈尤其机械硬盘或者是有程序在疯狂做页面交换。这种排查思路学到就是赚到。4. CPU到底是怎么干活的4.1 指令周期的三个基本步骤CPU执行指令的过程可以拆成三个节奏取指Fetch→译码Decode→执行Execute。取指阶段控制器把PC指向的内存地址发给存储器存储器返回该地址处的指令然后把这条指令放进指令寄存器IR同时PC自动加一条指令的长度为取下一条指令做准备。译码阶段控制器的译码电路分析IR里的指令格式确定操作码是什么、操作数在哪里。执行阶段运算器根据控制信号完成具体操作可能是算术运算、逻辑运算、访问内存或写回结果。这个取指→译码→执行的循环是CPU一切工作的基础。不管多复杂的程序、多牛逼的算法最终都分解成几百万条这样的机器指令。现代CPU为了提高吞吐率把这三个阶段进一步细化成十几级流水线——指令还没执行完下一条指令的取指已经开始就像工厂流水线一样每个工位同时处理不同指令的不同阶段。但流水线的设计也带来了新问题如果指令是分支跳转流水线可能会白做好多工作于是又引入了分支预测技术。这些高级技术后面会专门讲但现在把基础三段式搞扎实最重要。4.2 从ab看一条指令的完整旅程拿高级语言里一句最简单的c a b举例看看它在计算机里经历了什么。首先编译器和汇编器把这句话翻译成一条或几条机器指令常见的可能长这样从内存load变量a到寄存器R1load变量b到寄存器R2ADD R3, R1, R2把两个寄存器相加结果放入R3再把R3存回内存中c的地址。CPU拿到第一条load指令后控制器把指令地址放进地址总线内存把a的值放到数据总线上CPU把这个值存进R1第二条load同理。第三条ADD指令让ALU把R1和R2里的两个数相加结果送进R3第四条store指令把R3的值写回内存。整个过程中控制器负责发号施令运算器负责运算存储器负责读写总线负责搬运数据五大部件在这一瞬间全体参与工作。很多同学学到这里会困惑为什么不能直接在内存里做加法原因是CPU无法直接对内存数据运算它的运算器只跟寄存器打交道所以必须先把数据搬进寄存器再算。理解这一点你就明白为什么C语言里a和a在汇编层面有时会有差异为什么局部变量比全局变量访问更快——因为局部变量很可能会被优化到寄存器里而全局变量必须走内存。4.3 时钟频率与指令执行的节奏CPU里的所有操作都跟着一个统一的时钟信号走这个时钟就是节拍器。主频3.0GHz的意思是每秒有30亿个时钟周期每个周期约0.33纳秒。简单指令可能一个周期就能完成复杂指令可能需要几十个周期。所以主频越高CPU越快这个说法在同一个架构内是成立的但跨架构比较就不一定了——比如ARM的苹果M系列芯片主频没有Intel的酷睿高但同一周期能干更多的活儿IPC更高所以综合性能反而更好。这里要澄清一个概念IPS每秒指令数才是衡量CPU速度的更直接指标它等于主频乘以IPC。比如一颗CPU IPC5、主频3GHz那它每秒能执行150亿条指令如果另一颗CPU IPC3、主频4GHz每秒只能执行120亿条。只看主频会误判。选购CPU、服务器做性能评估的时候别迷信某个单一参数要综合看架构、IPC、缓存大小和访问延迟。关于主频还有一个常见的散热问题CPU在高负载下会主动降频热节流防止温度过高烧毁芯片。所以笔记本打游戏突然掉帧很多时候不是显卡不行是CPU过热降频了。你在BIOS或者软件里能看到实时的核心频率如果发现高负载时频率明显低于标称值就要检查散热器是否积灰老化——这也是判断硬件故障的经验之一。5. 连接各部件的关键桥梁总线5.1 三类总线各自负责什么计算机内部各部件不是孤立存在的它们之间的信息传递靠总线完成。总线是一组公共的传输线路按照传输内容分为三类数据总线Data Bus、地址总线Address Bus、控制总线Control Bus。数据总线负责传输数据本身可能是读到的内存数据、要写入内存的数据也可能是在输入输出设备间流动的数据。地址总线专门传输地址信息CPU想读内存哪个位置、想访问哪个I/O端口都在地址总线上发定位信号。控制总线负责传输各种控制信号比如读信号、写信号、时钟信号、中断请求信号用来约定操作的方向和时序。地址总线的位数决定了CPU能寻址的空间大小。举个例子如果地址总线是32位理论上最多能寻址2的32次方个地址也就是4GB所以32位系统最大支持4GB内存严格说还要扣除一部分硬件映射空间。64位系统地址总线通常是48位或52位物理地址理论空间巨大实际受限于主板和操作系统的实现。这个知识点经常在面试题里出现为什么32位系统装不了4GB以上内存答案就藏在地址总线位数里。5.2 总线的带宽和瓶颈总线的性能指标是带宽等于总线频率乘以数据总线宽度。比如早期的PCI总线是32位宽、33MHz带宽就是33MHz × 4字节 ≈ 133MB/s后来的PCIe 4.0 x16总线单通道约2GB/sx16就是32GB/s左右。总线带宽决定了数据能在部件之间以多快的速度搬运如果总线不够宽或频率不够高就算CPU和内存再快数据也堵在路上。对个人电脑来说最容易感知到的总线瓶颈其实是内存总线和硬盘接口。DDR4内存的带宽理论上可以到25GB/s以上而SATA接口的SSD瓶颈在600MB/s左右NVMe接口则可以跑到3500MB/s以上——这也是为什么换NVMe固态硬盘会明显感觉系统响应快了。理解总线瓶颈之后你在选购主板、硬盘时会更有判断力接口太老设备再好也白搭。另外现代CPU已经把原来的前端总线拆成了多个独立链路内存控制器集成在CPU内部直接连接内存延迟更低显卡走PCIe通道和CPU之间是点对点高速互连硬盘走芯片组的NVMe链路。这套复杂的互连拓扑依然是总线的现代变体只是从一根共享总线变成了多条专用通道目的只有一个减少共享争用、提高数据传输效率。6. 软件层的那些看不见的组成6.1 系统软件与应用软件的分层聊完硬件软件这边的基本组成也必须理清。软件系统从上到下可以分为应用软件、系统软件包含操作系统、编译器、数据库管理系统、驱动程序、以及固件。应用软件是用户直接使用的程序比如浏览器、Word、视频播放器、你写的Python脚本。系统软件则负责管理硬件资源、为应用软件提供运行环境。很多人分不清操作系统Windows/Linux和应用程序的边界。操作系统的基本组成也很有层次最核心的是内核负责进程管理、内存管理、文件系统、设备驱动外部是系统库和系统服务。内核运行在高特权级内核态应用程序运行在低特权级用户态两者通过系统调用接口交互。为什么要分两个特权级为了防止应用程序胡来破坏系统稳定性。比如你的程序试图直接写内存中其他进程的数据CPU的硬件机制会拦截这种操作并抛出权限异常——这个拦截能力本身就有CPU硬件比如x86的保护模式参与。6.2 操作系统在基本组成中的位置操作系统可以说是介于硬件和应用软件之间的中介。没有操作系统的时候程序员得自己控制中断、管理内存、调度任务有了操作系统你只需要调用API就行。Windows的表层是图形界面底层是ntoskrnl.exe这个内核Linux的表层是你用到的各种命令行工具和桌面环境底层是vmlinuz内核镜像。在这篇基本组成里理解操作系统的位置关键在于明白操作系统本身也是一种程序它存储在硬盘里开机后被引导程序加载到内存然后常驻内存运行。它和普通应用的区别在于特权级更高、生命周期更长、直接管理硬件资源。后面学操作系统时凡是提到进程调度内存分页文件系统你都可以回到这个最朴素的框架里找到归属。如果未来的方向是底层开发、系统开发那我建议在学习这一篇之后就接触一下最小内核实验这类项目亲自写一个能打印字符串的最简引导程序感受一下程序从硬盘加载到内存再被执行的过程。有了这种实感基本组成这张图就真正刻在你脑子里了。7. 初学者最容易绕晕的几个概念区分7.1 内存和外存的本质差别这个问题我见过至少几十个学生问过我电脑32G内存512G硬盘那我存文件到底存在哪回答很简单你平时双击的Word文档存在硬盘外存里但你打开这个文档时它的内容被加载到内存中供CPU处理你编辑的内容在保存前还只在内存里一旦断电没保存的修改全部丢失。这也是为什么软件提醒你是否保存更改——因为内存不保数据。为什么CPU不能直接运行硬盘里的程序因为硬盘速度太慢即便NVMe也在微秒级而CPU的时钟周期是纳秒级差了几百倍。如果把程序直接在硬盘上跑CPU每取一条指令就要等几微秒性能难以想象。所以程序必须先加载到内存内存速度虽然比CPU慢但还在纳秒级配合缓存命中性能才可用。记住一句话CPU访问外存必须经过内存DMA场景可以例外但目的还是先到内存缓冲区外存不能直接和CPU交换数据。7.2 位、字节、字长到底在说什么位bit是计算机存储的最小单位只能表示0或1。字节Byte是8个位组成的基本存储单位一个英文字母占1字节一个汉字在UTF-8编码下占3字节。字长Word是CPU一次能处理的位数比如64位CPU的字长就是64位也就是8字节。很多教材上写字长是计算机一次能处理的二进制位数这个定义其实有点模糊。严格说字长决定了ALU的宽度、寄存器的大小、以及地址总线的上限。比如32位CPU的寄存器宽度是32位ALU一次只能加两个32位数一条指令的地址字段也设计为32位。63位的整数它也能算但需要拆成两条甚至多条指令完成。这也是为什么32位系统上的C语言long类型通常是4字节而在64位系统上是8字节——因为它必须匹配CPU的字长。7.3 存储容量单位换算存储容量的换算也有个大坑。理论上1KB 1024B但硬盘厂商的标称容量用的是1KB 1000B所以一个标称512GB的SSD到手格式化后可用空间只有476GB左右这不是故障是进制不同。操作系统用的是二进制GiB厂商用的是十进制GBWindows资源管理器显示的GB其实是GiB。严谨场合下GiB、TiB这种单位才是二进制GB、TB是十进制。各类存储容量的现状也值得心里有数CPU缓存L2通常几百KB到几MB内存条现在主流16GB~64GBSSD主流512GB~2TB机械硬盘主流4TB~8TB。做服务器规划时缓存、内存、磁盘配比直接决定成本和性能配错了要么浪费预算要么频繁性能瓶颈。附这次写出来的一些实操心得按照惯例最后分享几个我在学习和教学过程中踩过、也见别人反复踩的坑。第一个心得别急着钻细节先画脑图。学习计算机系统基础时我见过太多人一头扎进Cache映射算法、流水线冲突分析、超标量调度这些硬核细节里结果生成迷路。我的方法是先用一张纸把CPU包含运算器和控制器→CPU通过总线连接内存和I/O→程序存在外存但运行时搬到内存→操作系统作为软件管理层这条主线画出来再看细节效率高很多。第二个心得把抽象概念翻译成身边的例子。存储层次就可以类比成你的桌面→书架→仓库桌面放正在写的文件寄存器书架放经常看的书Cache仓库放所有藏书内存硬盘。CPU就是那个坐在桌边不停找东西干活的人。例子可能不够精确但能帮你快速建立直觉后面再逐步修正。第三个心得做点小实验验证。如果你用的是Linux可以在终端跑一下lscpu看看缓存大小、核心数、主频跑一下free -h看内存再用dd测试硬盘读写速度对比不同存储层级的速度差异。这些操作成本极低但能让你把纸面概念变成真实感知。计算机系统基础不是靠背出来的是靠看和做慢慢建立体系。这篇内容只是打开了一扇门里面还有指令流水线、中断系统、存储层次扩充、并行计算等等一堆话题等着继续啃。只要你把基本组成和基本概念吃透后面每一步都会走得很踏实。
返回列表