摘要在 PC 游戏史上90 年代末是一个“蛮荒”与“神迹”并存的时代。我们曾惊叹于《三角洲部队》Delta Force那由 CPU 暴力计算体素Voxel堆砌出的广阔荒野也曾被《半条命》Half-Life中告别了僵硬帧动画、拥有灵活骨骼的科学家所震撼。然而在那个性能爆发的黄金十年所有划时代的技术突破最终都撞上了一堵无形的墙——“总线带宽Bus Bandwidth”。如果你是 1996 年前后的 PC 玩家你应该正深陷于 PCI 接口33MHz与初出茅庐的 AGP 1X66MHz带来的带宽焦虑。那是一个“总线即瓶颈”的时代CPU 与 GPU 像是被“柏林墙”隔开的异地恋数据在两者间的往返必须支付昂贵的“总线税”。为了让一个物体在屏幕上“转起来”开发者们经历了从 2.5D 纸片人到软件渲染再到 3D 加速卡的认知质变。但在传统的物理架构断层下CPU 在内存里计算出的顶点位移必须经历漫长的协议握手与内存拷贝才能抵达显存。这种拷贝延迟直接抹杀了 3D 渲染的实时性潜力迫使开发者不得不通过牺牲模型精度来换取勉强及格的帧率。有趣的是解决这个问题的终极答案早在 1996 年就由任天堂与 SGI 以一种近乎“孤注一掷”的方式交出了答卷。当 PC 玩家还在为 4MB 显存的同步效率争吵时N64 已经凭借统一内存架构UMA降临。它彻底消除了 CPU 与 GPU 之间的物理边界实现了真正意义上的 Zero-copy零拷贝。这种设计领先了时代二十年直到今天的 Apple Silicon M 系列芯片与 PS5 上它才重回舞台中心。今天我们将放下笨重的 IDE拿起 Vim重回那个 4MB 内存的方寸之地。通过 Libdragon SDK我们将在那块 CPU 与 GPU “同居”的内存上动手术去窥探那个由技术野心交织而成的图形世界。PC游戏的发展与崛起在那个时代曾流传着一个近乎神话的说法全球安装了《DOOM》的电脑数量甚至超过了 Windows 系统。凭借极具前瞻性的‘共享软件’分发模式这款游戏像病毒般在互联网雏形中疯狂蔓延无数企业与高校的局域网因员工和学生沉迷‘联机死斗’而集体瘫痪。在 90 年代中期玩家的词典里还没有‘FPS’人们将这一类游戏统称为‘DOOM 仿制品’。对于习惯了幻灯片式画面的玩家而言这种如丝般顺滑的 3D 动作体验简直是来自未来的技术启示。尽管其激进的血腥表现将其推向了舆论的风口浪尖使其沦为社会谴责游戏暴力的靶心但也正因这种‘禁忌感’它成为了整整一代青少年心中无法撼动的文化图腾。《毁灭战士》DOOM的诞生不仅仅是一个游戏的发布它被广泛认为是现代电子游戏史上最伟大的技术飞跃之一直接定义了“第一人称射击游戏FPS”这一门类。发布年代1993 年 12 月 10 日开发团队id Software。核心灵魂人物包括“天才程序员”约翰·卡马克John Carmack和“游戏设计狂才”约翰·罗梅洛John Romero发行背景当时 id Software 已经凭借《德军总部 3D》Wolfenstein 3D小有名气但他们想要制作一款更暗黑、更血腥、技术更先进的游戏。受电影《异形》和《鬼玩人》的影响他们构思了一个“太空陆战队在火星基地独自对抗地狱恶魔”的故事在 1993 年DOOM 展现的技术几乎领先了时代一个身位2.5D 引擎Doom Engine虽然角色是 2D 贴图但场景实现了前所未有的深度感。相比《德军总部 3D》只能有平坦的地板DOOM 引入了高低差楼梯、平台、非直角墙壁以及动态光影效果如闪烁的灯光。首创“死斗”DeathmatchDOOM 正式创造了“Deathmatch”这个词。它允许最多 4 名玩家通过局域网或拨号调制解调器进行竞技彻底开启了联机对战的时代。WAD 文件系统与 MOD 文化卡马克将游戏引擎与游戏数据关卡、图形、声音分离存储在.WAD文件中。这种开放性直接催生了早期的游戏 MOD 文化玩家可以自行设计关卡。注脚但当时 PC 的 CPU 性能不足以处理真实的 3D 投影矩阵而显卡还只是简单的“帧缓存显示器”于是开发者们被迫发明了一套精妙的欺骗视觉的方法。在 3D 游戏的蛮荒时代硬件的贫瘠迫使开发者成为了最伟大的“魔术师”。1993 年诞生的 《DOOM》其底层逻辑并非真正的 3D而是一张纯粹的 2D 矢量平面图。由于当时的硬件无力承担成千上万个三角形的透视变换约翰·卡马克John Carmack选择了一个极其天才的折中方案他通过剥夺玩家“上下看”的自由并将地图限制在没有重叠层的二维平面内从而将复杂的 3D 渲染降维成了一个极快的几何问题。利用 BSP空间分割 树CPU 可以像剥洋葱一样从近及远处理墙块这种对遮挡计算的极致规避让《DOOM》在算力匮乏的年代实现了超前的流畅感。这种“降维打击”的背后实质上是对 486 时代浮点运算FPU 缺陷的无奈妥协。尽管 486DX 历史性地将 FPU 封装进了 CPU 内部但其 x87 栈式架构极其低效——计算一条浮点乘法指令甚至需要 10 到 20 个时钟周期。在 486 上强行运行浮点 3D 矩阵效率就像是用手动拨号上网来跑流媒体帧率会瞬间跌入个位数。为此《DOOM》大规模使用了“定点数魔法”来绕过 FPU 的性能黑洞。技术奇点 -- BSP树在 1993 年那个连 486 都要缩屏跑游戏的年代卡马克将原本用于军事模拟和 CAD 领域的 BSP 算法引入了《DOOM》这不仅是技术的跨界更是一场关于“遮挡处理”的算力革命。在 3D 渲染中最痛苦的问题是可见性判断Visibility Determination。 传统的思路是像画家画画一样先画远处的物体再画近处的盖上去。PC 架构的总线带宽极低。如果 CPU 辛苦计算并填充了一个像素随后发现它被更近的墙挡住了那么之前的计算和总线传输就全部浪费了即 Overdraw。他需要一种方法能让 CPU 从近到远地渲染并且保证被画过的像素绝不重复填色。这个方法的名字叫BSP空间切割即在游戏运行前关卡编译器会选择一面墙作为“分割面”将整张地图切成两半左/右或前/后。然后再在两半空间里继续找墙切割直到每个子空间都是凸多边形。最终形成一棵二叉树。这个切割过程极其耗时所以是在地图打包时完成的。生成的 BSP 树记录了所有墙面、地板、天花板的拓扑结构信息。当玩家移动时CPU 只需要根据玩家当前的 (x, y) 坐标去遍历这棵二叉树。由于树是预先排好序的CPU 只需要通过简单的正负号判断就能瞬间知道哪些墙在玩家前面哪些在后面。配合 1D Z-Buffer在 DOOM 中是一组横向数组CPU 先渲染最近的墙。如果某个横向位置已经被填色后面的墙就直接被丢弃。这彻底解决了 Overdraw 问题极大节省了 486 脆弱的总线带宽。我们可以用一个二维平面切割的例子通过表格步进的方式来模拟 CPU 是如何通过一个简单的“点法式”数学判断瞬间决定渲染顺序的假设地图里有两面墙A 和 B玩家站在某个位置。墙 A 所在的直线。它把世界分成了“正面”和“背面”。数学原理墙 A 的直线方程为 : ax by c 0 将玩家坐标 (x, y) 代入 结果 0 玩家在 A 的正面 结果 0 玩家在 A 的背面假设我们的 BSP 树结构如下根节点墙 A正面分支墙 B背面分支墙 CCPU 渲染决策表从近到远渲染步骤玩家位置判断 (代入方程)逻辑结果动作优先处理近动作后续处理远1代入墙 A 的方程结果为 正玩家在 A 的 正面遍历 正面分支 (墙 B)遍历 背面分支 (墙 C)2进入 A 的正面分支看墙 B墙 B 是叶子节点渲染墙 B-3回溯到根节点 A-渲染墙 A-4进入 A 的背面分支看墙 C墙 C 是叶子节点渲染墙 C-最终渲染顺序B - A - C完全符合从近到远的物理遮挡。下面是一个简单的测试代码#include stdio.h typedef struct Node { float dist; // 分割平面到原点的距离 float normal[2]; // 分割平面的法向量 (2D 空间下) char wall_name; // 墙体标识 struct Node *front; // 正面子空间 struct Node *back; // 背面子空间 } BSPNode; /** * 递归遍历并渲染 BSP 树 * param node 当前节点 * param eye_x 玩家 X 坐标 * param eye_y 玩家 Y 坐标 */ void render_bsp(BSPNode *node, float eye_x, float eye_y) { if (node NULL) return; // 1. 计算点到直线的距离核心算法代入直线方程 // side 0 表示玩家在墙的正面side 0 表示在背面 float side (eye_x * node-normal[0] eye_y * node-normal[1]) - node-dist; if (side 0) { // 2. 玩家在正面先渲染正面分支近再画自己最后画背面远 render_bsp(node-front, eye_x, eye_y); printf(渲染墙体: %c (玩家在正面优先处理)\n, node-wall_name); render_bsp(node-back, eye_x, eye_y); } else { // 3. 玩家在背面顺序反转先画背面近再画自己最后画正面远 render_bsp(node-back, eye_x, eye_y); printf(渲染墙体: %c (玩家在背面优先处理)\n, node-wall_name); render_bsp(node-front, eye_x, eye_y); } } int main() { // 模拟一个简单的 BSP 树结构 // 假设墙 A 是分割面B 在 A 的正面C 在 A 的背面 BSPNode wallB { .wall_name B }; BSPNode wallC { .wall_name C }; BSPNode wallA { .dist 10, .normal {1, 0}, .wall_name A, .front wallB, .back wallC }; // 假设玩家站在坐标 (15, 0)此时玩家在 A 的正面 (15*1 - 10 5 0) printf(--- 玩家在 A 正面时 ---\n); render_bsp(wallA, 15, 0); return 0; }我们可以对比一下“暴力排序”和“BSP 树”处理 1000 面墙时的消耗特性暴力排序 (O(n log n))BSP 树 (O(n))核心算法每一帧都要对 1000 面墙进行距离排序每一帧做 1000 次加减法和正负号判断CPU 压力极高486 会直接卡死极低仅需判断点在直线的哪一侧数据状态每帧重新计算无法复用静态树结构永久复用总线占用高频繁交换排序后的索引低按树路径线性读取内存然而真正的转折点直到 Pentium奔腾 时代才到来。Intel 通过优化流水线将浮点执行周期缩短至 1-3 个周期这种算力的质变让卡马克终于有底气在 《Quake》 中抛弃 2.5D 的欺骗戏法转向真正的多边形矩阵变换。而随后 SSE流式 SIMD 扩展 指令集的引入更是让 PC 拥有了矢量处理能力顶点处理不再是单兵作战而是成倍地提升了吞吐量。至此PC 终于完成了从算法戏法到硬核计算的跨越但随之而来的却是那堵更难翻越的、由于物理隔离导致的“总线之墙”。通过这张表可以清晰地看到尽管 PC 的 CPU 算力在短短几年内实现了从‘栈式标量’到‘矢量 SIMD’的跨越但其基础架构始终没有摆脱‘内存-总线-显存’的远程运输模式。特性80486DX (x87 时代)Pentium III (SSE 时代)核心计算模式栈式标量 (Stack-based)矢量 SIMD (Streaming SIMD)3D 坐标运算逐个分量串行计算效率极低一条指令处理 4 个单精度浮点数并行能力无 (指令执行周期长达 10-20 周期)高 (单指令多数据并行处理)数据传输路径CPU - RAM - ISA/PCI - 显存CPU - RAM - AGP - 显存传输开销 (总线税)极高带宽极窄导致只能缩屏运行高即便有 AGP频繁搬运顶点仍是瓶颈渲染策略软件渲染、定点数魔法、2.5D 欺骗硬件加速、真实多边形、动态骨骼动画“尽管 PC 的 CPU 算力在短短几年内实现了从‘栈式标量’到‘矢量 SIMD’的跨越但其基础架构始终没有摆脱‘内存-总线-显存’的远程运输模式。这种架构决定了即便 CPU 算得再快只要数据还没‘搬’进显存屏幕就只能等待。这就是为什么在那个时代的 PC 极客眼中AGP 接口的出现就像是给乡间小道拓宽成了双车道虽然缓解了拥堵但依然无法实现真正的‘零延迟’直达。”下一期我们将进入 90 年代末最辉煌也最纠结的时刻。我们会拆解《三角洲部队》那广袤却模糊的体素荒野——为什么 CPU 算得出千米之外的草丛却送不到你的眼前我们会解构《半条命》的骨骼动画——当每个僵尸都想拥有灵魂总线带宽是如何变成一场噩梦的我们将看清 PC 开发者如何在那堵“幻影之墙”前竭尽全力并最终明白为什么远在京都的任天堂会选择一条截然不同的道路。
从现代视角审视统一内存架构(UMA)—— (1) PC 架构的崛起
摘要在 PC 游戏史上90 年代末是一个“蛮荒”与“神迹”并存的时代。我们曾惊叹于《三角洲部队》Delta Force那由 CPU 暴力计算体素Voxel堆砌出的广阔荒野也曾被《半条命》Half-Life中告别了僵硬帧动画、拥有灵活骨骼的科学家所震撼。然而在那个性能爆发的黄金十年所有划时代的技术突破最终都撞上了一堵无形的墙——“总线带宽Bus Bandwidth”。如果你是 1996 年前后的 PC 玩家你应该正深陷于 PCI 接口33MHz与初出茅庐的 AGP 1X66MHz带来的带宽焦虑。那是一个“总线即瓶颈”的时代CPU 与 GPU 像是被“柏林墙”隔开的异地恋数据在两者间的往返必须支付昂贵的“总线税”。为了让一个物体在屏幕上“转起来”开发者们经历了从 2.5D 纸片人到软件渲染再到 3D 加速卡的认知质变。但在传统的物理架构断层下CPU 在内存里计算出的顶点位移必须经历漫长的协议握手与内存拷贝才能抵达显存。这种拷贝延迟直接抹杀了 3D 渲染的实时性潜力迫使开发者不得不通过牺牲模型精度来换取勉强及格的帧率。有趣的是解决这个问题的终极答案早在 1996 年就由任天堂与 SGI 以一种近乎“孤注一掷”的方式交出了答卷。当 PC 玩家还在为 4MB 显存的同步效率争吵时N64 已经凭借统一内存架构UMA降临。它彻底消除了 CPU 与 GPU 之间的物理边界实现了真正意义上的 Zero-copy零拷贝。这种设计领先了时代二十年直到今天的 Apple Silicon M 系列芯片与 PS5 上它才重回舞台中心。今天我们将放下笨重的 IDE拿起 Vim重回那个 4MB 内存的方寸之地。通过 Libdragon SDK我们将在那块 CPU 与 GPU “同居”的内存上动手术去窥探那个由技术野心交织而成的图形世界。PC游戏的发展与崛起在那个时代曾流传着一个近乎神话的说法全球安装了《DOOM》的电脑数量甚至超过了 Windows 系统。凭借极具前瞻性的‘共享软件’分发模式这款游戏像病毒般在互联网雏形中疯狂蔓延无数企业与高校的局域网因员工和学生沉迷‘联机死斗’而集体瘫痪。在 90 年代中期玩家的词典里还没有‘FPS’人们将这一类游戏统称为‘DOOM 仿制品’。对于习惯了幻灯片式画面的玩家而言这种如丝般顺滑的 3D 动作体验简直是来自未来的技术启示。尽管其激进的血腥表现将其推向了舆论的风口浪尖使其沦为社会谴责游戏暴力的靶心但也正因这种‘禁忌感’它成为了整整一代青少年心中无法撼动的文化图腾。《毁灭战士》DOOM的诞生不仅仅是一个游戏的发布它被广泛认为是现代电子游戏史上最伟大的技术飞跃之一直接定义了“第一人称射击游戏FPS”这一门类。发布年代1993 年 12 月 10 日开发团队id Software。核心灵魂人物包括“天才程序员”约翰·卡马克John Carmack和“游戏设计狂才”约翰·罗梅洛John Romero发行背景当时 id Software 已经凭借《德军总部 3D》Wolfenstein 3D小有名气但他们想要制作一款更暗黑、更血腥、技术更先进的游戏。受电影《异形》和《鬼玩人》的影响他们构思了一个“太空陆战队在火星基地独自对抗地狱恶魔”的故事在 1993 年DOOM 展现的技术几乎领先了时代一个身位2.5D 引擎Doom Engine虽然角色是 2D 贴图但场景实现了前所未有的深度感。相比《德军总部 3D》只能有平坦的地板DOOM 引入了高低差楼梯、平台、非直角墙壁以及动态光影效果如闪烁的灯光。首创“死斗”DeathmatchDOOM 正式创造了“Deathmatch”这个词。它允许最多 4 名玩家通过局域网或拨号调制解调器进行竞技彻底开启了联机对战的时代。WAD 文件系统与 MOD 文化卡马克将游戏引擎与游戏数据关卡、图形、声音分离存储在.WAD文件中。这种开放性直接催生了早期的游戏 MOD 文化玩家可以自行设计关卡。注脚但当时 PC 的 CPU 性能不足以处理真实的 3D 投影矩阵而显卡还只是简单的“帧缓存显示器”于是开发者们被迫发明了一套精妙的欺骗视觉的方法。在 3D 游戏的蛮荒时代硬件的贫瘠迫使开发者成为了最伟大的“魔术师”。1993 年诞生的 《DOOM》其底层逻辑并非真正的 3D而是一张纯粹的 2D 矢量平面图。由于当时的硬件无力承担成千上万个三角形的透视变换约翰·卡马克John Carmack选择了一个极其天才的折中方案他通过剥夺玩家“上下看”的自由并将地图限制在没有重叠层的二维平面内从而将复杂的 3D 渲染降维成了一个极快的几何问题。利用 BSP空间分割 树CPU 可以像剥洋葱一样从近及远处理墙块这种对遮挡计算的极致规避让《DOOM》在算力匮乏的年代实现了超前的流畅感。这种“降维打击”的背后实质上是对 486 时代浮点运算FPU 缺陷的无奈妥协。尽管 486DX 历史性地将 FPU 封装进了 CPU 内部但其 x87 栈式架构极其低效——计算一条浮点乘法指令甚至需要 10 到 20 个时钟周期。在 486 上强行运行浮点 3D 矩阵效率就像是用手动拨号上网来跑流媒体帧率会瞬间跌入个位数。为此《DOOM》大规模使用了“定点数魔法”来绕过 FPU 的性能黑洞。技术奇点 -- BSP树在 1993 年那个连 486 都要缩屏跑游戏的年代卡马克将原本用于军事模拟和 CAD 领域的 BSP 算法引入了《DOOM》这不仅是技术的跨界更是一场关于“遮挡处理”的算力革命。在 3D 渲染中最痛苦的问题是可见性判断Visibility Determination。 传统的思路是像画家画画一样先画远处的物体再画近处的盖上去。PC 架构的总线带宽极低。如果 CPU 辛苦计算并填充了一个像素随后发现它被更近的墙挡住了那么之前的计算和总线传输就全部浪费了即 Overdraw。他需要一种方法能让 CPU 从近到远地渲染并且保证被画过的像素绝不重复填色。这个方法的名字叫BSP空间切割即在游戏运行前关卡编译器会选择一面墙作为“分割面”将整张地图切成两半左/右或前/后。然后再在两半空间里继续找墙切割直到每个子空间都是凸多边形。最终形成一棵二叉树。这个切割过程极其耗时所以是在地图打包时完成的。生成的 BSP 树记录了所有墙面、地板、天花板的拓扑结构信息。当玩家移动时CPU 只需要根据玩家当前的 (x, y) 坐标去遍历这棵二叉树。由于树是预先排好序的CPU 只需要通过简单的正负号判断就能瞬间知道哪些墙在玩家前面哪些在后面。配合 1D Z-Buffer在 DOOM 中是一组横向数组CPU 先渲染最近的墙。如果某个横向位置已经被填色后面的墙就直接被丢弃。这彻底解决了 Overdraw 问题极大节省了 486 脆弱的总线带宽。我们可以用一个二维平面切割的例子通过表格步进的方式来模拟 CPU 是如何通过一个简单的“点法式”数学判断瞬间决定渲染顺序的假设地图里有两面墙A 和 B玩家站在某个位置。墙 A 所在的直线。它把世界分成了“正面”和“背面”。数学原理墙 A 的直线方程为 : ax by c 0 将玩家坐标 (x, y) 代入 结果 0 玩家在 A 的正面 结果 0 玩家在 A 的背面假设我们的 BSP 树结构如下根节点墙 A正面分支墙 B背面分支墙 CCPU 渲染决策表从近到远渲染步骤玩家位置判断 (代入方程)逻辑结果动作优先处理近动作后续处理远1代入墙 A 的方程结果为 正玩家在 A 的 正面遍历 正面分支 (墙 B)遍历 背面分支 (墙 C)2进入 A 的正面分支看墙 B墙 B 是叶子节点渲染墙 B-3回溯到根节点 A-渲染墙 A-4进入 A 的背面分支看墙 C墙 C 是叶子节点渲染墙 C-最终渲染顺序B - A - C完全符合从近到远的物理遮挡。下面是一个简单的测试代码#include stdio.h typedef struct Node { float dist; // 分割平面到原点的距离 float normal[2]; // 分割平面的法向量 (2D 空间下) char wall_name; // 墙体标识 struct Node *front; // 正面子空间 struct Node *back; // 背面子空间 } BSPNode; /** * 递归遍历并渲染 BSP 树 * param node 当前节点 * param eye_x 玩家 X 坐标 * param eye_y 玩家 Y 坐标 */ void render_bsp(BSPNode *node, float eye_x, float eye_y) { if (node NULL) return; // 1. 计算点到直线的距离核心算法代入直线方程 // side 0 表示玩家在墙的正面side 0 表示在背面 float side (eye_x * node-normal[0] eye_y * node-normal[1]) - node-dist; if (side 0) { // 2. 玩家在正面先渲染正面分支近再画自己最后画背面远 render_bsp(node-front, eye_x, eye_y); printf(渲染墙体: %c (玩家在正面优先处理)\n, node-wall_name); render_bsp(node-back, eye_x, eye_y); } else { // 3. 玩家在背面顺序反转先画背面近再画自己最后画正面远 render_bsp(node-back, eye_x, eye_y); printf(渲染墙体: %c (玩家在背面优先处理)\n, node-wall_name); render_bsp(node-front, eye_x, eye_y); } } int main() { // 模拟一个简单的 BSP 树结构 // 假设墙 A 是分割面B 在 A 的正面C 在 A 的背面 BSPNode wallB { .wall_name B }; BSPNode wallC { .wall_name C }; BSPNode wallA { .dist 10, .normal {1, 0}, .wall_name A, .front wallB, .back wallC }; // 假设玩家站在坐标 (15, 0)此时玩家在 A 的正面 (15*1 - 10 5 0) printf(--- 玩家在 A 正面时 ---\n); render_bsp(wallA, 15, 0); return 0; }我们可以对比一下“暴力排序”和“BSP 树”处理 1000 面墙时的消耗特性暴力排序 (O(n log n))BSP 树 (O(n))核心算法每一帧都要对 1000 面墙进行距离排序每一帧做 1000 次加减法和正负号判断CPU 压力极高486 会直接卡死极低仅需判断点在直线的哪一侧数据状态每帧重新计算无法复用静态树结构永久复用总线占用高频繁交换排序后的索引低按树路径线性读取内存然而真正的转折点直到 Pentium奔腾 时代才到来。Intel 通过优化流水线将浮点执行周期缩短至 1-3 个周期这种算力的质变让卡马克终于有底气在 《Quake》 中抛弃 2.5D 的欺骗戏法转向真正的多边形矩阵变换。而随后 SSE流式 SIMD 扩展 指令集的引入更是让 PC 拥有了矢量处理能力顶点处理不再是单兵作战而是成倍地提升了吞吐量。至此PC 终于完成了从算法戏法到硬核计算的跨越但随之而来的却是那堵更难翻越的、由于物理隔离导致的“总线之墙”。通过这张表可以清晰地看到尽管 PC 的 CPU 算力在短短几年内实现了从‘栈式标量’到‘矢量 SIMD’的跨越但其基础架构始终没有摆脱‘内存-总线-显存’的远程运输模式。特性80486DX (x87 时代)Pentium III (SSE 时代)核心计算模式栈式标量 (Stack-based)矢量 SIMD (Streaming SIMD)3D 坐标运算逐个分量串行计算效率极低一条指令处理 4 个单精度浮点数并行能力无 (指令执行周期长达 10-20 周期)高 (单指令多数据并行处理)数据传输路径CPU - RAM - ISA/PCI - 显存CPU - RAM - AGP - 显存传输开销 (总线税)极高带宽极窄导致只能缩屏运行高即便有 AGP频繁搬运顶点仍是瓶颈渲染策略软件渲染、定点数魔法、2.5D 欺骗硬件加速、真实多边形、动态骨骼动画“尽管 PC 的 CPU 算力在短短几年内实现了从‘栈式标量’到‘矢量 SIMD’的跨越但其基础架构始终没有摆脱‘内存-总线-显存’的远程运输模式。这种架构决定了即便 CPU 算得再快只要数据还没‘搬’进显存屏幕就只能等待。这就是为什么在那个时代的 PC 极客眼中AGP 接口的出现就像是给乡间小道拓宽成了双车道虽然缓解了拥堵但依然无法实现真正的‘零延迟’直达。”下一期我们将进入 90 年代末最辉煌也最纠结的时刻。我们会拆解《三角洲部队》那广袤却模糊的体素荒野——为什么 CPU 算得出千米之外的草丛却送不到你的眼前我们会解构《半条命》的骨骼动画——当每个僵尸都想拥有灵魂总线带宽是如何变成一场噩梦的我们将看清 PC 开发者如何在那堵“幻影之墙”前竭尽全力并最终明白为什么远在京都的任天堂会选择一条截然不同的道路。