图灵奖系列 · DoggyDad 原创
John Cocke:他用"少即是多"改变了计算机,从手机到超算都在用他的RISC哲学
John Cocke:他用"少即是多"改变了计算机,从手机到超算都在用他的RISC哲学
ANSWER-FIRST SUMMARY
本文回答什么问题
John Cocke:他用"少即是多"改变了计算机,从手机到超算都在用他的RISC哲学
- 主题分类:图灵奖系列
- 关键词:图灵奖、计算机历史、编程语言、算法、人工智能、数据库
- 人物实体:John Cocke
图灵奖第二十二届(1987)| John Cocke:他用”少即是多”改变了计算机,从手机到超算都在用他的RISC哲学
一句话概括:当所有人都在往CPU里塞更多指令时,他说:“让硬件简单,让编译器聪明。“这一逆向思维催生了RISC革命,改变了整个计算机产业。
🏆 获奖简介
John Cocke(约翰·科克)是RISC架构的开创者、编译器优化理论的奠基人、计算机体系结构的革命家。
- 出生时间:1925年5月30日
- 出生地点:美国北卡罗来纳州夏洛特
- 逝世时间:2002年7月16日(享年77岁)
- 获奖年份:1987年
- 获奖原因:在计算机设计理论与实践方面的重大贡献,特别是精简指令集计算机(RISC)的开创性工作
为什么他是第二十二位? 在1970-80年代,计算机设计的主流思想是”复杂指令集(CISC)“——让CPU支持越来越多、越来越复杂的指令。Cocke却反其道而行之,通过IBM 801项目证明了”精简指令集(RISC)“的优越性。这不仅是技术路线的胜利,更是设计哲学的革命。今天,全球99%的智能手机都使用基于RISC理念的ARM处理器,这一切都可以追溯到Cocke的开创性工作。
🚀 他的重大贡献
1. RISC(精简指令集计算机)思想:少即是多的革命
简单理解:想象两位厨师,一位有100种专用工具(切丝器、削皮器、压蒜器…),另一位只有一把菜刀但刀法精湛。RISC就是后者——用少量简单的指令,通过巧妙组合实现所有功能。
历史背景:
- 1970年代主流:CISC(复杂指令集计算机)占据市场,设计者们不断添加新指令,试图用硬件直接实现各种高级功能。
- 代表产品:Intel x86、IBM System/360——指令集庞大,单条指令可能执行多个操作,但也导致硬件复杂、功耗高、难以优化。
Cocke的洞察:
- 20/80法则:通过分析大量实际程序,Cocke发现程序执行时间的80%都花在了20%的简单指令上(如加载、存储、简单算术),那些复杂的指令很少被使用。
- 流水线的瓶颈:复杂指令执行时间不一,难以实现高效的流水线(Pipeline),就像工厂流水线上有的工序需要1分钟,有的需要10分钟,整体效率受制于最慢环节。
- 编译器的潜力:与其在硬件中实现复杂操作,不如让编译器将高级语言翻译成简单指令序列,这样硬件可以更快、更高效。
RISC的核心原则:
- 指令简单统一:每条指令执行时间相同或相近,便于流水线调度
- 加载/存储架构:只有专门的加载(Load)和存储(Store)指令访问内存,其他指令只操作寄存器
- 大量寄存器:提供更多寄存器减少内存访问
- 固定指令长度:简化指令解码,提高效率
IBM 801项目:
- 时间:1975年启动,Cocke担任首席架构师
- 目标:为电话交换系统设计高性能处理器
- 成果:801处理器证明了RISC理念的可行性,虽然是内部项目未商业化,但其设计理念深刻影响了后续的RISC处理器
为什么重要?
- 性能革命:同样制程下,RISC处理器通常比CISC快2-4倍
- 催生了ARM:今天全球99%的智能手机都使用基于RISC理念的ARM处理器
- 影响深远:MIPS、SPARC、PowerPC、RISC-V等主流架构都是RISC的直系后代
- 云计算基石:现代数据中心的高性能服务器大量采用RISC架构
通俗类比:如果把CPU比作运动员,CISC就像要求运动员会100个复杂动作的全能选手,而RISC则是专注于几个基本动作但练到极致的专项冠军。后者更容易达到巅峰状态,也更容易通过训练(编译优化)提升表现。
2. 编译器优化:让代码”聪明地跑”
简单理解:编译器就像指挥家,同样的乐谱(源代码),好的指挥能让乐队(硬件)演奏出更优美的音乐(高效执行)。Cocke是编译器优化领域的”首席指挥家”。
核心贡献:
2.1 数据流分析(Data Flow Analysis)
什么是数据流分析? 在编译过程中追踪变量的定义、使用和生命周期,就像追踪物流系统中货物的流向。
Cocke的贡献:
- 区间分析(Interval Analysis):将程序控制流图分解成”区间”,使分析更高效
- 活性分析(Live Variable Analysis):确定变量在哪些地方”还活着”(会被使用),为寄存器分配提供依据
实际应用:
int x = 5; // x被定义
int y = x + 3; // x被使用
int z = y * 2; // x已"死亡",可重用其寄存器
通过活性分析,编译器知道x在第3行后不再使用,可以将其占用的寄存器分配给其他变量。
2.2 寄存器分配(Register Allocation)
为什么重要? 寄存器比内存快100倍以上,但数量有限(通常只有几十个)。如何把最常用的变量放进寄存器是编译器的关键任务。
Cocke的贡献:
- 图着色算法:将寄存器分配问题转化为图论中的着色问题
- 优先级启发式:根据变量使用频率和生命周期分配优先级
通俗理解:想象一个只有10个车位的停车场,数据流分析告诉你哪些车(变量)什么时候会来、会停多久,寄存器分配算法就是排班表,确保最需要停车的车总有位置,而不常用的车就停在远处(内存)。
2.3 循环优化(Loop Optimization)
为什么关注循环? 程序的大部分执行时间都花在循环中。优化循环就像优化生产线上重复最多的环节,收益最大。
Cocke开创的技术:
- 循环不变代码外提(Loop-Invariant Code Motion):
// 优化前
for (i = 0; i < n; i++) {
result[i] = x * y + array[i]; // x*y每次循环都重算
}
// 优化后(编译器自动完成)
temp = x * y; // 只算一次
for (i = 0; i < n; i++) {
result[i] = temp + array[i];
}
- 归纳变量消除(Induction Variable Elimination):消除循环中的冗余计算
- 循环展开(Loop Unrolling):减少循环控制开销
实际影响:这些技术可以让循环密集型程序(如科学计算、图像处理)性能提升数倍。
3. 流水线调度与指令级并行
简单理解:现代CPU像工厂流水线,可以同时处理多个指令的不同阶段。Cocke研究如何最优地安排指令顺序,让流水线始终满载运行。
核心概念:
- 流水线(Pipeline):将指令执行分为取指、解码、执行、访存、写回等阶段,不同指令可以在不同阶段并行
- 危险(Hazards):不同指令之间的依赖关系可能导致流水线停顿
Cocke的贡献:
- 指令调度算法:在保证程序语义不变的前提下,重新安排指令顺序以减少流水线停顿
- 推动编译器与硬件协同:RISC的简单指令使得编译时调度成为可能
举例:
; 原始顺序(有依赖,会停顿)
LOAD R1, [addr1] ; 从内存加载到R1
ADD R2, R1, R3 ; 必须等R1加载完成
LOAD R4, [addr2] ; 与上面无关
; 调度后(减少停顿)
LOAD R1, [addr1]
LOAD R4, [addr2] ; 提前执行,填补等待时间
ADD R2, R1, R3 ; 此时R1已准备好
现实意义:今天的超标量处理器(Superscalar)可以同时执行多条指令,但仍然依赖编译器提供良好调度的代码。
4. IBM的Stretch、ACS与POWER架构
IBM Stretch(7030):
- 时间:1950年代末
- 目标:为洛斯阿拉莫斯国家实验室设计超级计算机
- Cocke的角色:参与指令集设计与优化
- 影响:虽然商业上不太成功,但引入了很多创新(如流水线、多功能单元),是Cocke早期探索高性能架构的试验田
IBM ACS(Advanced Computing System):
- 时间:1960年代
- Cocke的角色:主要架构师之一
- 贡献:探索了分支预测、乱序执行、寄存器重命名等技术,这些在当时过于超前,项目被取消,但技术被后续产品吸收
POWER架构:
- 全称:Performance Optimization With Enhanced RISC
- 时间:1990年发布
- 与Cocke的关系:POWER直接继承了801项目的RISC理念与Cocke的优化技术
- 商业成功:成为IBM服务器与工作站的核心,后来演变为PowerPC(与Apple、Motorola联合),曾用于Mac、游戏机(Xbox 360、PS3)
5. 并行计算与向量化
贡献:
- 研究如何利用向量处理器(Vector Processor)加速科学计算
- 探索编译器如何自动识别和利用并行性
- 为后来的自动并行化编译器奠定基础
现代回响:
- 今天的SIMD指令(如SSE、AVX、NEON)延续了向量化思想
- GPU通用计算(CUDA、OpenCL)也受其影响
🌍 对世界的深远影响
1. 移动互联网的幕后英雄
今天全球超过100亿台设备(智能手机、平板、物联网设备)使用ARM处理器,而ARM的核心设计理念直接源自Cocke的RISC思想。没有Cocke,就没有今天的移动革命。
2. 让编译器从”翻译器”变成”优化器”
在Cocke之前,编译器只是简单地将源代码翻译成机器码。Cocke的工作让编译器成为性能提升的关键工具,现代编译器(LLVM、GCC)中的核心优化技术都可以追溯到他的开创性研究。
3. 软硬件协同设计的典范
RISC的核心哲学是”将复杂性从硬件转移到软件”,这一思想深刻影响了整个行业:
- **专用芯片(ASIC)**设计:如AI芯片(TPU、NPU)采用简单高效的指令集,依赖编译器优化
- 异构计算:CPU+GPU+FPGA的协同,需要编译器的智能调度
- 云计算:虚拟化与容器技术也需要软硬件紧密配合
4. 开源芯片运动的理论源头
RISC-V是当今最火的开源指令集架构,它的”V”代表第五代RISC,直接致敬Cocke开创的RISC传统。RISC-V正在推动芯片设计的民主化,让任何人都可以设计自己的处理器。
🏆 获奖理由(通俗版)
ACM官方表彰:“表彰他在计算机设计理论与实践方面的重大贡献,包括精简指令集计算机(RISC)、编译器优化技术,以及并行计算架构。”
更通俗的理解: 如果把计算机发展比作建筑史,早期设计者的思路是”建造功能越多越好的瑞士军刀式大楼”,而Cocke提出”建造简单模块化的大楼,用智能管理系统(编译器)协调一切”。这一转变让建筑更快、更省、更强,影响了此后几十年的所有设计。
他是一位真正的”架构师的架构师”,不仅设计了伟大的架构,更建立了设计伟大架构的方法论。
👤 个人生平与传奇
生平时间线
- 1925年:出生于北卡罗来纳州夏洛特
- 1946年:获得杜克大学机械工程学士学位
- 1956年:获得杜克大学数学博士学位
- 1956年:加入IBM研究部门,开始长达37年的IBM生涯
- 1975年:启动IBM 801项目,开创RISC架构
- 1980年代:全力推动编译器优化与并行计算研究
- 1987年:获得图灵奖
- 1992年:获得美国国家科学奖章
- 1994年:获得美国国家工程院Draper奖(工程界的”诺贝尔奖”)
- 2002年:7月16日在纽约州Valhalla逝世,享年77岁
人格魅力:天才的谦逊
极致专注的研究者:
- Cocke是那种可以为一个技术问题钻研数月的纯粹科学家
- 他更享受解决问题本身,对名利看得很淡
- IBM内部流传:“Cocke的办公室里堆满了论文草稿,但他最不擅长的就是写完整的论文”
不善言辞的 影响者:
- 虽然发表的正式论文不多,但他的思想通过无数讨论、内部报告和合作者传播
- 许多IBM的工程师和后来的RISC先驱都受到过他的直接指导
- 他更像是”思想的源泉”而非”著作等身的学者”
完美主义者:
- 对技术细节极度挑剔,总是追求”最优解”
- 这种完美主义既成就了他的伟大创新,也导致一些项目(如ACS)因”过于超前”而商业化失败
谦逊的大师:
- 获得图灵奖后,他说:“我只是做了一些让我着迷的工作,能影响真实世界真的很幸运。”
- 从不居功,总是强调团队贡献
经典轶事
1. “Cocke定理”的传说 在IBM内部,工程师们会开玩笑说:“如果Cocke说可以优化,那一定可以;如果他说优化到极限了,你再试100次也没用。“他对性能极限有一种近乎直觉的把握。
2. 与学术界的”脱节” Cocke的大部分工作在IBM内部完成,很多成果都被标为”机密”或仅以技术报告形式流传。直到RISC思想在学术界(Berkeley、Stanford)独立”再发现”时,人们才意识到Cocke早在十年前就完成了基础工作。这也是为什么很多教科书同时提到”Cocke的IBM 801”和”Berkeley的RISC-I”——后者让RISC走向公众,前者才是真正源头。
3. 差点错失图灵奖 由于Cocke发表论文很少,且很多工作未公开,图灵奖评委会一度对其贡献了解不足。是IBM的同事和受他影响的学者们联名力荐,详细阐述他的影响,才让评委会意识到”原来那么多革新技术都源自这个人”。
💭 为什么他值得纪念?
1. 改变了整个行业的思维方式
Cocke最大的贡献不是某个具体的芯片或算法,而是”简洁优雅”的设计哲学:
- 硬件:复杂不是力量,效率才是
- 软件:智能的编译器可以释放硬件潜力
- 协同:软硬件不是对立,而是协同进化
这一哲学今天已成共识,但在40年前是革命性的。
2. 他的工作经得起时间考验
RISC不是昙花一现的潮流,而是持续50年并将继续主导未来的架构方向。从1980年代的工作站,到2000年代的服务器,再到今天的手机、物联网,RISC始终站在舞台中央。
3. 他启发了无数后继者
直接或间接受Cocke影响的人包括:
- David Patterson(2017年图灵奖得主):Berkeley RISC项目领导者,后来设计出RISC-V
- John Hennessy(2017年图灵奖得主):Stanford MIPS项目领导者,后担任Stanford校长和Google母公司董事长
- 数百位RISC架构的设计者与优化编译器的开发者
可以说,Cocke是”架构师们的导师”。
4. 他证明了工业研究的价值
在一个推崇”发论文、争引用”的学术环境中,Cocke选择了另一条路:扎根工业界,解决真实问题,用产品检验思想。他的成功表明,伟大的计算机科学不一定诞生在大学实验室,也可以来自企业的研发部门。
🔍 技术深度:RISC vs CISC详解
CISC的困境
复杂指令的吸引力:
- 一条指令完成复杂功能(如字符串拷贝、多项式运算),似乎更”高级”
- 减少指令数量,节省内存(当年内存昂贵)
实际问题:
- 硬件复杂:需要大量晶体管实现复杂指令,提高成本和功耗
- 执行时间不一:有的指令1个时钟周期,有的需要上百个,难以流水线化
- 编译器难优化:指令太多太杂,编译器难以选择最优指令组合
- 80%的指令很少用:大量晶体管浪费在几乎不用的指令上
RISC的突破
设计原则:
- 指令少而精:通常100条左右,每条都高频使用
- 统一格式:所有指令长度相同(如32位),简化解码
- 单周期执行:大部分指令一个时钟周期完成,易于流水线
- Load/Store分离:只有Load和Store访问内存,其他指令只操作寄存器
性能优势:
- 更高频率:简单电路可以跑更高时钟频率
- 流水线效率:5级甚至更多级流水线,吞吐量大增
- 编译器友好:指令规整,编译器可以深度优化
功耗优势:
- 对移动设备至关重要
- ARM的成功很大程度源于低功耗
混合趋势
现实是复杂的:
- x86的进化:虽然指令集仍是CISC,但内部微架构已RISC化(将复杂指令拆成简单微操作)
- RISC的扩展:ARM也不断增加指令(如SIMD),模糊了界限
结论: 今天的高性能处理器都是”RISC核心+CISC兼容”,Cocke的RISC哲学已内化为行业共识。
💭 给开发者的启示
1. 写编译器友好的代码
编译器优化依赖代码模式识别。写清晰的代码不仅可读性好,也更容易被优化。
// ❌ 编译器难优化:指针别名问题
void bad_example(int *a, int *b, int *c, int n) {
for (int i = 0; i < n; i++) {
a[i] = b[i] + c[i]; // 编译器不确定a,b,c是否重叠
}
}
// ✅ 编译器友好:使用restrict关键字
void good_example(int * restrict a,
int * restrict b,
int * restrict c, int n) {
for (int i = 0; i < n; i++) {
a[i] = b[i] + c[i]; // 编译器知道无重叠,可以向量化
}
}
2. 理解循环优化
Cocke发明的循环优化技术今天仍在使用。理解它们可以帮你写出更快的代码。
# ❌ 循环内有不变计算
def slow_version(data, factor):
result = []
for item in data:
# math.sqrt(factor)每次循环都重算!
transformed = item * math.sqrt(factor) + 10
result.append(transformed)
return result
# ✅ 循环不变代码外提
def fast_version(data, factor):
# 只算一次
sqrt_factor = math.sqrt(factor)
result = []
for item in data:
transformed = item * sqrt_factor + 10
result.append(transformed)
return result
# 现代编译器会自动做这个优化,但明确写出来:
# 1. 保证优化生效
# 2. 提高代码可读性
3. 利用数据局部性
RISC强调寄存器的重要性。现代CPU有多级缓存,访问模式很重要。
// ❌ 缓存不友好:列优先访问行优先存储的数组
void cache_unfriendly(int matrix[1000][1000]) {
for (int j = 0; j < 1000; j++) { // 列
for (int i = 0; i < 1000; i++) { // 行
matrix[i][j] += 1; // 跳跃访问,缓存失效多
}
}
}
// ✅ 缓存友好:行优先访问
void cache_friendly(int matrix[1000][1000]) {
for (int i = 0; i < 1000; i++) { // 行
for (int j = 0; j < 1000; j++) { // 列
matrix[i][j] += 1; // 连续访问,缓存命中率高
}
}
}
// 性能差距可达10倍以上!
4. 理解分支预测
现代CPU有复杂的分支预测器,但仍有局限。
// ❌ 分支难预测:随机模式
int sum_if_positive(int *data, int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
if (data[i] > 0) { // 随机true/false,预测失败多
sum += data[i];
}
}
return sum;
}
// ✅ 无分支版本:在某些情况下更快
int sum_if_positive_branchless(int *data, int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
// data[i] > 0 ? data[i] : 0
int positive_part = data[i] & -(data[i] > 0);
sum += positive_part;
}
return sum;
}
// 注意:不是所有情况都适用,需要profile
5. 充分利用SIMD指令
Cocke的向量化思想演变为今天的SIMD。
#include <immintrin.h>
// 普通版本
void add_arrays(float *a, float *b, float *c, int n) {
for (int i = 0; i < n; i++) {
c[i] = a[i] + b[i];
}
}
// SIMD版本:AVX可以一次处理8个float
void add_arrays_simd(float *a, float *b, float *c, int n) {
int i;
for (i = 0; i <= n - 8; i += 8) {
__m256 va = _mm256_loadu_ps(&a[i]);
__m256 vb = _mm256_loadu_ps(&b[i]);
__m256 vc = _mm256_add_ps(va, vb);
_mm256_storeu_ps(&c[i], vc);
}
// 处理剩余元素
for (; i < n; i++) {
c[i] = a[i] + b[i];
}
}
// 速度提升:理论上8倍,实际约5-6倍
关键建议:
- 先写清晰的代码,让编译器自动优化
- 用
-O3 -march=native编译选项 - Profile确认瓶颈后再手动优化
- 学习查看编译器生成的汇编代码
❓ 常见问题
Q1: RISC真的比CISC更快吗?为什么x86还在主导桌面市场?
A: 这是个复杂问题:
- 理论上:同等制程和设计投入下,RISC更高效
- 实际上:现代x86处理器内部已经是RISC架构(micro-ops),只是保持了CISC的指令集兼容性
- 为什么x86仍主导桌面:
- 生态锁定:几十年的软件积累
- Intel/AMD投入巨大:世界级的设计团队和fab
- 性能够用:大部分用户不需要最极致的能效比
关键洞察:今天的CPU竞争已经不是纯粹的RISC vs CISC,而是生态、工艺、设计投入的综合较量。但Cocke的RISC理念已经赢了——所有高性能CPU内核都是R ISC化的。
Q2: 为什么ARM在移动设备上打败了x86?
A: 功耗是关键:
- ARM的优势:
- RISC架构天生功耗低
- 从一开始就为低功耗设计
- 简洁的指令集减少晶体管数量
- x86的劣势:
- 兼容性负担:需要支持40年的旧指令
- 历史包袱:很多电路用于兼容性而非效率
当移动时代到来,功耗>性能,ARM的时代就来了。这完美验证了Cocke”简洁优雅”的设计哲学。
Q3: 编译器优化有极限吗?人工汇编还有意义吗?
A: 有极限,但很难达到:
- 编译器做得很好的:
- 寄存器分配
- 循环优化
- 死代码消除
- 常量折叠
- 编译器做不好的:
- 跨函数/跨文件的全局优化(LTO在改善)
- 领域特定的算法优化(如BLAS库手写汇编)
- 极端对延迟敏感的代码
建议:
- 99%的情况:相信编译器
- 1%的情况(性能关键路径):考虑手写SIMD/汇编
- 总是先profile,再优化
Q4: RISC-V会取代ARM吗?
A: 可能性存在,但路还很长:
- RISC-V的优势:
- 完全开源,无授权费
- 设计现代,吸取了40年经验
- 模块化,适合定制
- ARM的优势:
- 成熟生态:工具链、库、文档完善
- 海量软件支持
- 大公司背书(苹果、高通、三星)
预测:短期内ARM仍主导,长期RISC-V在IoT、嵌入式、专用芯片领域会快速增长。两者可能共存,就像Linux和Windows。
Q5: 普通程序员需要了解这么底层的知识吗?
A: 取决于你的目标:
- 不需要深入了解:
- Web开发、App开发、数据分析
- 抽象层次高,性能瓶颈在网络/数据库
- 需要了解:
- 系统编程、嵌入式、游戏引擎
- 高性能计算、数据库内核
- 编译器、虚拟机开发
建议:
- 每个程序员都应该理解基本概念(缓存、分支预测、SIMD)
- 专注性能的领域需要深入掌握
- Cocke的故事告诉我们:理解底层,才能设计更好的上层
📚 延伸阅读与学习路径
入门级
- 《计算机组成与设计:硬件/软件接口》(Patterson & Hennessy)
- 经典教材,作者是RISC先驱,深受Cocke影响
- RISC与CISC对比章节必读
进阶级
- 《现代编译原理》(Appel)
- 涵盖Cocke开创的优化技术
- 《计算机体系结构:量化研究方法》(Patterson & Hennessy)
- 深入分析RISC设计原则与性能
专业级
- IBM 801研究报告(查阅IBM技术档案或计算机历史博物馆)
- RISC-V规范文档
- 现代RISC的集大成者,理解它就理解了Cocke遗产
在线资源
- 计算机历史博物馆:有Cocke的访谈视频和技术展览
- ACM Digital Library:搜索Cocke的经典论文
- RISC-V Foundation:了解RISC思想的最新演进
🌟 精神遗产:从Cocke身上学到的
1. 质疑常识的勇气
当所有人都认为”复杂即强大”时,Cocke敢于说”简单才是终极智慧”。在技术领域,往往是那些挑战主流的思想最后改变世界。
2. 长期主义
从1975年801项目到1987年获图灵奖,再到1990年代RISC全面开花,Cocke坚持一个方向超过20年。真正的创新需要耐心。
3. 协同的智慧
RISC的成功证明,最优解往往不在单一层面(纯硬件或纯软件),而在于跨层协同。这一思想适用于任何复杂系统。
4. 谦逊与专注
Cocke从不追逐热点,不擅长自我营销,只专注于技术本身。但最终,“是金子总会发光”,真正的贡献会被历史铭记。
总结语: John Cocke是一位真正的”隐形冠军”。他的名字或许不如冯·诺依曼、图灵那样家喻户晓,但他的思想已融入每一台计算设备的DNA。每当你滑动手机屏幕,每当你的笔记本电脑流畅运行,都有Cocke智慧的影子在闪耀。
他用一生证明了:伟大的技术不在于炫目的复杂,而在于优雅的简洁;不在于堆砌功能,而在于深刻理解本质。“少即是多”不仅是美学原则,更是工程哲学。这束始于1970年代的RISC之光,将继续照亮计算的未来。
最后更新: 2024年12月 本文为图灵奖系列文章,旨在以通俗方式介绍计算机科学先驱的贡献
DISCUSSION
评论与补充