
一句话1不是某种神秘的东西它通常就是某个地方存着一小堆电子或者某根导线上有较高的电压。电脑只是约定电压高于某个值算 1低于某个值算 0。前面讲网络时我们一直在说字节“位”“包”。这一篇往下挖到底一个位在物理上到底是什么。一、生活里的例子一排水杯桌上摆着 8 个水杯杯里有水 → 记作1杯里没水 → 记作08 个杯子就能表示一个字节比如01000001字母 A。但现实中会有几个麻烦水杯的问题电脑里对应的问题杯子有细缝水会慢慢漏掉电荷会泄漏所以 DRAM 需要不停刷新杯里只剩半杯水算有还是没有需要一个阈值来判断想知道有没有水只能倒出来看DRAM 的读取是破坏性的读完要写回杯子用久了会裂闪存SSD的擦写寿命“充电状态就是杯子里有水”。下面看看不同的杯子分别是什么。二、先搞清楚充电是什么意思电荷与电压电荷物质里带电粒子的多少。电子带负电一个电子的电量约为 1.6 × 10⁻¹⁹ 库仑。电压两点之间的电势差可以理解为水位差。“充电并不是装进了电”而是把电子从一边搬到另一边让两边形成电压差。电容器最简单的杯子┌─────┐ ← 一块金属板电子被抽走带正电 │ 绝缘 │ ← 中间是绝缘层电子过不去 └─────┘ ← 另一块金属板电子堆积带负电存了多少电荷取决于两个因素Q C × V 电荷量 电容大小 × 电压电荷存在那里两板之间就有电压电路可以检测到这个电压。1其实是一个电压范围数字电路不要求电压正好是某个值而是按范围判断电压 1.0V ┤██████████ 判定为 1高电平 0.7V ┤────────── 高电平阈值 │ 不确定区 ← 落在这里结果不可靠电路设计会尽量避免 0.3V ┤────────── 低电平阈值 0V ┤██████████ 判定为 0低电平中间留出来的空白区叫噪声容限即使有点干扰、有点漏电只要没跨过阈值0 还是 01 还是 1。这就是数字比模拟可靠的根本原因模拟信号每一点误差都会被记录下来数字信号只要不越过阈值误差就会被抹掉。三、DRAM内存条最典型的充电 1你电脑里的内存条就是 DRAM。每个位由1 个晶体管 1 个电容组成简称 1T1C字线Word Line选中这一行 │ ┤ 晶体管开关 位线 ───────┤ Bit Line │ ═╪═ 电容存电荷 │ 接地状态电容含义充了电有电压1也可以反过来约定没充电接近 0V0一个1到底有多少电子现代 DRAM 单元的电容大约在10 fF飞法10⁻¹⁵ 法拉量级工作电压约 1VQ C × V ≈ 10 × 10⁻¹⁵ × 1 10⁻¹⁴ 库仑 电子数 ≈ 10⁻¹⁴ ÷ (1.6 × 10⁻¹⁹) ≈ 60,000 个你内存里的一个1大约就是几万个电子挤在一个极小的电容里。16GB 内存有约 1370 亿个这样的电容。漏电 → 必须刷新绝缘层不完美电子会慢慢漏走。几十毫秒后“1就可能变成0”。所以内存控制器会定期把每一行读出来再写回去标准规定通常每64ms内要把所有行刷新一遍。写入 1 ████████████ 过了一会████████░░░░ 电子在漏 刷新 ████████████ 读出来判定为 1重新充满这就是DRAM中 D 的意思Dynamic动态需要不停维护。断电后刷新停止几秒到几分钟内数据就消失了。读取会破坏数据位线本身的电容比单元电容大得多可能大 10 倍以上。打开晶体管后单元里的电荷分摊到位线上位线电压只变化几十到一百多毫伏。1. 先把位线预充到中间电压比如 0.5V 2. 打开晶体管单元电荷和位线混合 3. 位线电压变成 0.55V单元原来是 1或 0.45V原来是 0 4. 灵敏放大器Sense Amplifier把这个微小差别放大成完整的 1 或 0 5. 放大后的结果顺便写回单元恢复电荷这就像用一个大杯子去量小杯子里的水倒进去后只能看到水面轻微上升还得用放大镜判断然后再把水倒回来。四、SRAMCPU 缓存不靠存电荷靠互相撑住CPU 的 L1、L2、L3 缓存用的是 SRAM每个位用6 个晶体管┌──→ 反相器 A ──┐ │ ▼ └─── 反相器 B ←─┘ A 输出 1 → B 输出 0 → A 继续输出 1 → ……两个反相器把 1 变 0、把 0 变 1 的电路首尾相接形成互相锁定的稳定状态。DRAMSRAM怎么存电容里的电荷两个反相器互相维持的电压每位晶体管数1 个 1 个电容6 个需要刷新吗需要不需要只要通电速度较慢很快密度 / 成本密度高、便宜占地大、贵用途内存条CPU 缓存、寄存器附近SRAM 的1不是一堆静止的电子而是电源持续供电撑住的一个电压状态。就像两个人背靠背站着互相支撑只要有力气供电谁都不会倒。这也解释了前面讲性能时说的缓存很快但很小因为每一位都很贵。五、闪存SSD、U 盘、手机存储把电子关进笼子闪存断电后数据还在靠的是浮栅Floating Gate或电荷捕获层控制栅 ═════════════ 绝缘层很薄 ┌───────────┐ │ 浮 栅 │ ← 四面都被绝缘层包住的笼子 └───────────┘ 绝缘层很薄 ═════════════ 源极 沟道 漏极操作原理写入编程加较高电压让电子隧穿绝缘层进入浮栅量子隧穿效应保存断电后电子被绝缘层困住可以保存数年读取浮栅里的电子会改变晶体管的导通门槛阈值电压测一下导不导通就知道擦除加反向高压把电子拉出来⚠️ 这里充电反而表示 0NAND 闪存中按惯例状态浮栅值擦除后电子很少1编程后电子较多0所以**充电 1只是一种约定不是物理定律**。一块全新、擦除干净的闪存读出来全是0xFF全是 1。一个位用多少电子越来越少类型每个单元存几位需要区分的电荷等级SLC1 位2 级MLC2 位4 级TLC3 位8 级QLC4 位16 级工艺越先进单元越小每个等级之间相差的电子数就越少有时只有几十个电子的量级。QLC 要在同一个笼子里分辨 16 种满的程度就像在一个杯子里分辨 16 种水位。后果原因寿命短擦写次数少每次隧穿都会轻微损伤绝缘层笼子越来越漏需要强力纠错ECC、LDPC少几个电子就可能被误判长期断电可能丢数据电子会极其缓慢地漏出速度较慢写入要多次充一点、测一下逐步逼近目标电荷量六、其他地方的1位置1是什么CPU 寄存器触发器类似 SRAM 的锁存结构输出的高电压CPU 内部导线导线被充到高电压导线本身也有微小电容机械硬盘磁性颗粒的磁化方向没有电荷光盘反射面上的凹坑与平面之间的变化网线电压在一段时间内的变化模式还经过编码光纤光脉冲的有无或强弱Wi-Fi / 4G电磁波的相位和幅度组合一个符号可以携带多位上一组网络文章里讲的包“带宽”到了最底层就是这一行网线上的电压跳变、光纤里的光闪烁。网卡把这些物理信号翻译成 0 和 1再交给内核。七、为什么电脑会发热因为一直在充放电CPU 里有几十亿个晶体管导线和晶体管栅极都相当于微小电容。每次一个位从 0 变 1就要给这些电容充电从 1 变 0就要放电能量变成热量。CPU 的动态功耗大致是P ≈ α × C × V² × f α每个周期有多少比例的电路在翻转 C被充放电的电容总量 V电压 f频率结论说明电压影响最大平方关系电压降低 10%功耗约降低 19%所以降压是笔记本、手机省电的主要手段频率越高越热每秒充放电次数更多数据翻转越多越耗电一直不变的位几乎不耗动态功耗和游戏开发的联系手机游戏发烫降频本质就是每秒充放电的次数和电量太多热量散不出去。降低帧率、减少无用计算等于减少充放电次数。八、“1会不会自己变成0”会原因说明漏电DRAM 靠刷新、闪存靠纠错和定期重写来应对宇宙射线 / 高能粒子粒子穿过芯片产生电荷可能翻转一个位单粒子翻转高海拔、航天设备更明显Rowhammer反复高频访问 DRAM 某一行相邻行的电容受干扰漏电更快可能翻位曾被用于安全攻击电压不稳 / 过度超频信号还没稳定到阈值以上就被读取闪存磨损绝缘层损坏电荷关不住应对方法方法用在哪里ECC 内存服务器内存自动纠正单位错误校验和 / 哈希网络包、文件下载CDN 那一篇的下载后校验哈希闪存控制器的 LDPC 纠错SSD 内部冗余与重试网络可靠传输ACK 与重传前面网络篇讲的校验 重传和内存的 ECC 是同一个思想物理世界的 0 和 1 并不完美可靠性是靠上层机制补出来的。九、用代码模拟一下 DRAM 漏电与刷新用一个简单模型直观感受电荷按比例泄漏低于阈值就读错。usingSystem;classDramCell{publicdoubleVoltage;// 当前电压constdoubleVdd1.0;// 满电电压constdoubleThreshold0.5;// 判定阈值constdoubleLeakPerMs0.01;// 每毫秒泄漏 1%简化publicvoidWrite(boolbit)Voltagebit?Vdd:0.0;publicvoidTick(doublems)Voltage*Math.Pow(1-LeakPerMs,ms);publicboolRead(){boolbitVoltageThreshold;Write(bit);// 读取是破坏性的读完写回相当于刷新returnbit;}}classProgram{staticvoidMain(){varnoRefreshnewDramCell();varwithRefreshnewDramCell();noRefresh.Write(true);withRefresh.Write(true);for(intt0;t120;t10){Console.WriteLine(${t,4}ms 不刷新:{noRefresh.Voltage:F2}V $定期刷新:{withRefresh.Voltage:F2}V);noRefresh.Tick(10);withRefresh.Tick(10);if(t%4030)withRefresh.Read();// 每 40ms 刷新一次}Console.WriteLine($不刷新读到:{(noRefresh.Read()?1:0)});// 0数据丢了Console.WriteLine($定期刷新读到:{(withRefresh.Read()?1:0)});// 1数据还在}}运行后能看到不刷新的那个单元大约 70ms 后电压跌破 0.5V“1变成了0”定期刷新的始终保持在阈值以上。真实 DRAM 的泄漏速度和刷新机制比这复杂得多这里只是演示原理。十、常见的误解误解实际情况“1 就是有电流流过”通常是有电压电荷积累不一定有电流SRAM 和 DRAM 保持状态时几乎没有电流“充电一定是 1”只是约定NAND 闪存里电子多反而是 0“1 就是正好 1 伏”是一个电压范围靠阈值判断“内存断电马上清零”DRAM 电荷要逐渐泄漏低温下甚至能保留数秒以上冷启动攻击就利用了这一点“硬盘也是靠充电”机械硬盘靠磁化方向不靠电荷“数字信号不会出错”会只是有阈值和纠错机制挡住了大部分错误“存储里的数据是永久的”闪存会老化和漏电长期不通电的 SSD 有丢数据风险重要数据要备份一句话总结1在物理上通常是某个地方积累了一些电子形成了高于阈值的电压。DRAM电容里约几万个电子会漏电所以每几十毫秒要刷新一次读取时还会被破坏、需要写回。SRAM两个反相器互相锁住的电压状态只要通电就能保持快但贵。闪存电子被隧穿关进浮栅断电也能保存而且按惯例电子多的是 0。不管哪一种1都只是物理状态 人为约定 阈值判断。计算机之所以可靠是因为在这些并不完美的物理状态之上又叠加了阈值、刷新、纠错和校验。