- SignalDesk1小时前
LuciusChthollius, CS @ ETHz | 计算机科学·丹麦语·德语·知识 查看知乎原文 大家都知道电脑的使用体验取决于硬件和软件。简要来说,软件一般是根据当时硬件的基准来开发的,所以从年以上的长周期来看,随着硬件的提升,而新的软件则会跟进新的硬件,老的设备带不动新的软件是很正常的现象,所以这是个不可避免的现象。 为了让这篇回答不浪费各位看客的时间,我们先从一些理想化的情况来观察一台电脑的生命周期。 硬件老化 假设我们拥有一台刚买的新电脑,从开机的那一刻起,我们完全冻结其软件状态,也就是我们 不连接网络,不更新操作系统,不安装新软件 。 我们首先要审视的是固态硬盘(SSD),毕竟电脑的任何操作,本质上都是数据的读取与写入。 现代 NAND 闪存是通过将电子困在浮栅(Floating Gate)或电荷俘获层(Charge Trap)中来存储数据的。每次写入或擦除数据时,都需要施加高电压,迫使电子通过极薄的二氧化硅绝缘层(Tunnel Oxide):这种高压强制电子穿越的过程,会随着时间推移物理性地破坏绝缘层的分子结构,导致电子被困在绝缘层中或发生泄漏。 [1] 随着绝缘层的物理损伤,存储单元(Cell)中电荷状态的边界变得模糊。原本应该读取为 1 的电位,可能会漂移成 0。这在物理学上表现为原始误码率(Raw Bit Error Rate, RBER)的指数级上升。 SSD 控制器是一个带有自己 CPU 和内存的微型计算机。当发现 RBER 上升时,它必须动用更高级、更复杂的纠错算法,如低密度奇偶校验码(LDPC)。 新电脑的 NAND 单元非常健康,读取时可以直接输出数据(硬判决:Hard Decision)。但用了几年后,控制器为了纠正大量错误,必须进行多次不同参考电压的读取(软判决:Soft Decision),并进行复杂的数学运算。这意味着,哪怕操作系统请求的只是一个几 KB 的小文件,SSD 控制器在底层可能经历了多次读取重试和高负荷的纠错计算。 物理层增加的几十微秒延迟,在系统 I/O 栈中会被逐级放大,表现为程序加载时的轻微停滞感。 随着电脑长期使用,SSD 内部必然充满零碎的有效与无效数据。因为 NAND 闪存不能直接覆盖写入,必须先擦除再写入,且擦除的最小单位 Block 远大于写入单位 Page。 当你需要写入一个新文件时,SSD 控制器必须先在后台把混合了有效数据的 Block 搬运到新位置,然后再擦除旧 Block。这就是垃圾回收(Garbage Collection)。 在可用空间减少、碎片增加的老旧电脑上,原本只需写入 1MB 的数据,底层物理闪存可能由于 WAF 激增而实际被强制写入了 3-4MB 的数据。这不仅让 SSD 的高速缓存迅速耗尽,还会导致底层 I/O 通道被后台搬运任务阻塞。由于存储 I/O 是现代操作系统的主要瓶颈,底层 I/O 队列的阻塞会直接导致 CPU 线程被迫挂起,你在宏观上的体感就是「点了一下鼠标,但程序图标弹跳了半天才打开」。 [2] 接下来,我们观察计算核心(CPU/GPU)。它们的计算能力并未随时间衰减:晶体管只要没坏,1+1 依然等于 2。然而它们维持峰值计算能力的时间变短了。 CPU/GPU 的硅芯片与散热器之间并不是完全平整的,必须涂抹导热硅脂来填补微小缝隙,以降低热阻。 当你开启重负载程序(如编译代码、玩游戏)时,芯片迅速升温膨胀;关机或待机时,芯片降温收缩。这种日复一日的热胀冷缩,会导致芯片和散热器由于热膨胀系数(CTE, Coefficient of Thermal Expansion)不同,产生微小的横向剪切力。 这种剪切力会像泵一样,慢慢将硅脂从芯片中央挤到边缘。这在工程学上被称为泵出效应(Pump-out Effect)。同时,硅脂中的挥发性溶剂会随时间干涸。加上散热风扇在几年内必然积累微小的灰尘,改变了空气流体动力学特性。 [3] 根据傅里叶热传导定律: 导热介质的物理退化导致热阻 增加。同样功耗下,热量无法快速传导至空气中,芯片的结温(Junction Temperature, )上升速度比新买时快得多。 所有的现代处理器都内置了动态电压与频率调整机制(DVFS, Dynamic Voltage and Frequency Scaling)。这是一个极底层的硬件自我保护回路。当温度传感器探测到 逼近物理极限(如 ,防止硅晶穿透或熔断)时,微代码会强制介入,降低工作电压和时钟频率。 最终的感觉大概就是,新电脑编译一个项目,CPU 可以维持在 4.5GHz 全速运行 5 分钟不降频。但两三年后,由于硅脂干涸和热阻变大,CPU 可能全速运行 10 秒钟就撞到温度墙,被迫降频到 2.0GHz。指令执行的周期被拉长,界面渲染掉帧,体感不卡才怪。 最后,我们还要考量供电系统,这个对于笔记本电脑等带电池的设备来说非常重要。 随着充放电循环,锂离子电池内部的电解液会分解,在负极表面形成并不断加厚固态电解质界面膜(SEI Layer)。同时,部分活跃的锂离子会变成无法游离的死锂。这一化学过程直接导致电池的交流 / 直流内阻(Internal Resistance, )随使用年份显著上升。 [4] 现代操作系统的响应速度,极度依赖 CPU 在毫秒级的爆发性能,比如我们熟知 Intel 的 PL2/PL4 状态或 AMD 的 Precision Boost。当你在桌面上拖动一个窗口,CPU 可能会在几十毫秒内瞬间请求超过 100 瓦的功率。 根据欧姆定律 。当电流( )瞬间剧增,而电池老化导致内阻( )非常高时,电池输出给主板的电压( )会发生瞬间深跌(Voltage Sag)。如果这个电压跌破了数字电路保持高低电平所需的阈值,电脑就会瞬间黑屏重启。 硬件工程师为了防止老旧设备频繁死机,会在主板固件或操作系统内核中写入保护逻辑:当检测到电池老化时,强制锁定 CPU/GPU 的峰值电流请求上限。最典型的工业界实证就是 Apple 曾经引发巨大争议的「降速门」:为了防止旧 iPhone 因电压瞬跌而关机,iOS 内核会根据电池化学年龄,限制 CPU 的最高频率和突发功耗。这在 PC 笔记本上也同样适用(尤其是不插电时)。你的老电脑变卡,往往是因为它的供电系统已经无法支撑高性能爆发,而固件也在因此限制之。 软件熵增 我们假设一个更为日常的场景:即使你没有升级任何操作系统版本,也没有安装新的庞大软件,甚至硬件仍处于巅峰状态,仅仅是随着使用时间的推移,系统依然会变慢。这在计算机科学中被称为软件腐烂或系统熵增。 首先是我们的操作系统。众所周知,操作系统的核心职责是管理资源。而在长时间使用后,系统的管理成本会呈现非线性增长。主流现代操作系统(Windows, macOS, Linux)属于抢占式多任务系统(Preemptive Multitasking)。当你使用电脑一两年后,虽然你自认为只打开了浏览器和办公软件,但在后台,系统中已经悄悄积累了大量的驻留程序,如各软件的自动升级服务、硬件驱动的监听面板、防病毒软件的后台扫描、各种无用的 Shell 扩展。同时,Windows 的注册表或类 Unix 系统的配置文件目录( /etc, ~/.config )中积累了海量的孤儿键值和历史记录。 这种状态的累积,导致系统在启动或唤醒时,需要遍历和加载比新电脑多出数倍的节点与服务。这构成了系统状态的高熵局面。 根据操作系统调度器的原理,哪怕这些后台驻留程序什么都不干,它们也会定期通过定时器中断(Timer Interrupts)唤醒 CPU,以检查是否需要执行任务。这时,每次切换任务,CPU 必须执行上下文切换(Context Switch),将当前正在运行的程序状态保存到内存中,然后把后台服务的状态加载进来。新电脑后台只有几十个进程,而老电脑后台可能有 114514 个进程。即使老电脑的 CPU 使用率看起来只有 5%,但这 5%是由极其频繁的、碎片化的上下文切换组成的,这就很卡了。 从 CPU 的微架构来看的话,我们知道 CPU 访问 L1 缓存只需~1 纳秒,而访问主存(RAM)需要~100 纳秒,因此 CPU 运行速度完全依赖于缓存命中率(Cache Hit Rate)。真正导致感觉卡的,不是保存和恢复寄存器的那几微秒,而是缓存被破坏。当 CPU 从你正在玩的游戏或正在滚动的网页切换到某个后台自动更新服务时,L1/L2 缓存中原本属于游戏或网页的数据会被挤出,填入后台服务的代码和数据。几毫秒后,CPU 切回前台程序,发现缓存里找不到需要的数据了,也就是说发生了 Cache Miss。 Memory architecture CPU 被迫去缓慢的内存中重新拉取数据。这导致指令流水线停顿(Pipeline Stall),IPC(每周期执行指令数)暴跌。在宏观体感上,就是鼠标移动出现了几十毫秒的微卡顿或者网页滚动时掉帧。 另外考虑到使用时长,一个软件开发的老问题不得不提。具体来说就是很多开发者在写软件时,假设的是一个干净的、小规模的测试环境。但在用户电脑上长期运行后,本地数据的累积会让优秀的算法也变成灾难。 现代桌面软件极度依赖本地数据库(特别是 SQLite)。你的浏览器历史记录、聊天记录、邮件客户端的索引、甚至操作系统的文件搜索索引,本质上都是一个个不断膨胀的数据库文件。一台新电脑,这些数据库是空的;三年后,你的浏览器历史记录可能有几十万条,聊天软件的本地数据库可能高达数 GB,包含上千万条消息。 大多数关系型数据库使用 B-Tree 或 B+Tree 作为索引数据结构。其查询的时间复杂度为 :从算法理论来看数据量 哪怕从 1 万增加到 1000 万,树的深度也只会增加几个层级。但是,计算机科学不仅是数学,它必须在冯·诺依曼架构的物理限制下运行。 当数据库就几 MB、还非常小时,整棵 B+Tree 被操作系统缓存在内存(RAM / Page Cache)中,遍历几个树节点的耗时是纳秒级的。然而,当数据库膨胀到几个 GB 时,RAM 无法装下整个索引树。此时,当你尝试搜索一个历史联系人,或者浏览器尝试在地址栏为你自动补全网址时,系统必须遍历 B+Tree。 因为节点不在内存中,CPU 触发缺页中断,操作系统必须去硬盘(哪怕是 SSD)中把树节点所在的块(Block)读取到内存。原本在内存中只需 100 纳秒 的节点跳转,现在变成了 100 微秒的磁盘 I/O 操作,慢了千倍有余。如果 SSD 恰好因为物理衰退的写入放大而处于繁忙状态,这个延迟会被进一步拉长到数毫秒。 所以算法复杂度还是 但物理常数项被改变就会让时间延迟显著增加。 尽管固态硬盘不需要像机械硬盘那样进行物理磁头寻道,但文件系统的逻辑碎片化依然致命。经过长年累月的下载、删除、解压操作,文件系统的元数据树变得极其庞大且分散。当你打开一个包含几万个小文件的旧文件夹时,文件系统资源管理器必须逐个读取这些文件的元数据,包含文件名、图标、权限、最后修改时间。由于记录的极度分散,操作系统发起的是海量的、不可预测的小区块随机读取。这正是任何存储介质(包括最顶级的 NVMe SSD)的薄弱环节。 软件膨胀 在前面的两部分中,我们假设了一台完全与世隔绝的电脑。然而,现实中的计算设备是全球软件生态系统的端点。一旦你的电脑连上互联网,开始更新系统、更新浏览器、使用最新版的日常软件,它就不可避免被时间淘汰。 在工业界,最昂贵的资源早已不是 CPU 的计算周期,而是程序员的开发时间和维护成本。 抽象漏洞法则(The Law of Leaky Abstractions)由软件工程专家 Joel Spolsky 于 2002 年提出:「计算机科学中的任何问题都可以通过增加一个间接层(抽象层)来解决。」 为了降低跨平台开发的成本,现代企业不再为 Windows、macOS 和 Linux 分别使用原生语言(C++/Swift)开发三个版本的软件。取而代之的是,工业界广泛采用了 Electron、React Native 或各类 Web Wrapper 技术。 当你打开一个基于这个逻辑开发的现代的聊天软件(如 Slack、Discord 甚至新版微信、QQ)、笔记软件或代码编辑器时,你以为你只是打开了一个几十 MB 的轻量级文字处理工具。但在系统底层,每一个这样的软件都向内存中加载了一个完整的 Chromium 浏览器渲染引擎和一个 Node.js 运行时。 十年前,一个纯粹由 C++ 和 Win32 API 编写的原生聊天软件,内存占用通常在 50MB 左右。而今天,一个基于 Electron 的聊天软件,启动即消耗 500MB 到 1GB 的内存。这被称为软件膨胀(Software Bloat)。 后果就是,比方说你的老电脑可能只有 8GB 内存。新买时,这 8GB 内存足以支撑操作系统和十几个原生应用。但现在,仅开启浏览器和两个基于 Electron 的日常软件,8GB 内存就被吃干抹净。 一旦 RAM 耗尽,操作系统别无选择,只能启用页面交换(Paging / Swap),将内存中的数据硬塞进慢成千上万倍的硬盘中。此时,你在应用间切换(例如从微信切回浏览器),由于数据必须从硬盘重新载入内存,系统会发生严重的缺页中断(Page Fault),产生长达数秒的假死现象。 即使撇开跨平台框架不谈,现代编程语言的内存管理机制对于老旧硬件来说也很麻烦。 我们 ETHZ 的老校友、图灵奖得主 Niklaus Wirth 在 1995 年的 IEEE 论文 A Plea for Lean Software 中提出:软件变慢的速度永远快于硬件变快的速度。工业界则有著名的戏谑:“Andy gives, Bill takes away.”(安迪·格鲁夫 /Intel 提供多少硬件性能,比尔·盖茨 / 微软的软件就会吃掉多少)。 随着 16GB 甚至 32GB 内存成为行业标配,开发者失去了优化内存的动力,体现了经济学上的杰文斯悖论:资源越丰富、效率越高,该资源的消耗反而越大。 现代软件多采用自动内存管理的语言(如 Java, C#, JavaScript/V8 引擎)编写。这些语言不需要程序员手动释放内存,而是依靠垃圾回收器(GC(定期扫描和清理无用数据。我们都知道垃圾回收机制需要大量的空闲内存裕量(Headroom)才能高效运行。 当老旧电脑的内存处于拥挤状态时,新软件的 GC 引擎会被频繁触发。
- 情报分类:硬件与数码
- 分类依据:内容涉及硬件、数码产品或通信卡
- 信息来源:资讯 / 知乎日报
- 发布时间:2026/10/18 07:02:41
- 暂无回复