回到首页

输入关键词,多个关键词用空格分隔。

← CSAPP 原始课程笔记 · 系列目录

深入理解计算机系统 第 1 课 总览

约 5 分钟
本页目录

这门课是 CMU 的镇校神课,其课程编号 15213 也正是 CMU 的邮编,故有:不上 15213,等于没来过 CMU。课本 CSAPP 也是非常经典的计算机教材。虽然我之前大概看过一次,不过这次跟着 CSAPP 的作者一起,再学习一次。

第一节课主要是介绍课程的总体内容,给大家一个整体的认识。


小技巧

  • Mac 下利用 lldb 来进行基本概念的试验,如: $ print 50000 * 50000
  • 利用 gdb 来阻止发送 bomblab 的结果到 server 中,这样就不会被扣分

大部分计算机学科的课程强调抽象,比如说抽象数据类型还有渐进分析。抽象很强大,但是也有其局限性,尤其是在出 bug 的时候。这时,我们就需要去理解这些抽象的底层实现。

上这门课可以让你成为一个更有效率的程序员——高效寻找和消除 bug,理解和调整程序的性能表现,更重要的是,这门课几乎是所有其他重要学科的先导课程:编译器,操作系统,网络,计算机架构,嵌入式系统,存储系统等等。

接下来会介绍五个必须知道的事实,不然很可能会因为理解不到位而无法找出问题所在。

Great Reality #1 Ints are not Integers, Floats are not Reals

Ints 不是整数,Floats 不是实数。这句话的意思是,因为计算机表现能力的限制,使得整型和浮点型和真实数学的表现有一些差异。

参考下图,举两个简单的例子:

  • x2≥0x^2 \ge 0 一定成立吗?
    • 对于浮点数来说,一定成立
    • 对于整型来说,不一定,可能会有溢出的情况
    • 可以通过 lldb 前两次的输出发现问题所在
  • (x+y)+z=x+(y+z)(x+y)+z = x + (y+z) 一定成立吗?
    • 对于无符号/有符号整型来说,一定成立
    • 对于浮点数来说,不一定,可能会因为精度问题被舍入
    • 可以通过 lldb 后两次输出发现问题所在

计算机运算虽然结果可能很奇怪,但绝不是随机数,所有的算术操作都有重要的数学性质。但是这种性质和我们日常生活中使用的数学性质有一些差异。造成这个现象主要的原因是精度表达的限制(32位,64位)。

对于 Integer 的操作,满足 rings 性质:Commutativity, Associativity, Distributivity。

对于 Float 的操作,满足 ordering 性质:Monotonicity, Signs

Great Reality #2 You've Got to Know Assembly

虽然我们不需要用汇编语言写程序,但是需要在机器执行那一级去理解汇编,例如:

  • 高级语言模型崩溃,出现 bug 时,理解程序的行为
  • 了解编译器所做的优化以及代码中比较低效的部分
  • 编译器输出机器代码
  • 操作系统必须管理进程状态
  • 创造/对抗恶意软件时,x86 汇编是必须的

Great Reality #3 Memory Matters

Random Access Memory Is an Unphysical Abstraction

随机访问内存是一个非物理的抽象,实际上

  • 内存不是没有边界的,需要进行分配和管理
  • 内存引用 bug 很麻烦,因为可能导致在一段时间或者代码的不同位置出现问题
  • 内存的性能不是平均的,缓存和虚拟内存可以极大影响性能,利用好内存系统的特性可以极大提高性能

C/C++ 没有提供任何内存保护机制,可能出现:

  • 数组越界引用
  • 非法的指针
  • 滥用 malloc/free

这就容易导致非常恶心的 bug,因为我们没办法判断是程序本身的 bug,还是系统和编译器的 bug。一旦出现问题,其实根源很早就埋下,不容易发现。这时候可以怎么办呢?

  • 用带保护机制的语言来写:Java, Ruby, Python, ML, ...
  • 理解可能出现的问题
  • 利用查找引用错误的工具(例如 Valgrind)

Great Reality #4 There's more to performance than asymptotic complexity

不要被所谓的大 O 计算忽悠了,复杂度比这个要复杂得多。即使是 O(1) 的部分,可能也是很重要的因素,哪怕可以数出来运算的数量,也无法预测性能表现。需要在多个层次进行优化:算法,数据表示,程序流程以及循环。

要做这些优化,就需要理解系统本身:程序是如何编译执行的,如何去衡量程序性能表现并且找出瓶颈,如何在不破坏代码模块性和通用性的前提下提高性能

Great Reality #5 Computers do more than execute programs

计算机不只是执行程序而已,还需要进行数据的传输,因此 IO 系统对于程序的稳定和性能都非常关键。在这个网络时代,有了更高的连接要求,根据不同的系统层次,有:

  • 匿名进程的并行操作
  • 从不可靠的介质复制(比方说 U 盘)
  • 跨平台兼容性
  • 复杂的性能问题

这门课是几乎所有计算机学科的基础课,整个学期有 7 个 lab 加上期中与期末考试。可以通过访问『shark machines』来进行试验,用 andrew id 登录

linux> ssh shark.ics.cs.cmu.edu

下面大致介绍下主要知识点和不同的 lab 的重点

Programs and Data

  • 主题
    • 位操作,数学计算,汇编程序
    • C 控制流程的表示以及数据结构
    • 体系架构和编译器
  • 作业
    • L1(datalab):操作 bits
    • L2(bomblab):拆除一个二进制炸弹
    • L3(attacklab):基本的代码注入攻击

The Memory Hierarchy

  • 主题
    • 内存技术,内存层级,缓存,磁盘,locality
    • 体系架构和操作系统
  • 作业
    • L4(cachelab):做一个缓存模拟器并且进行优化,与此同时学习如何在程序中利用 locality

Exceptional Control Flow

  • 主题
    • 硬件异常,进程,进程控制,Unix 信号,非本地跳转(nonlocal jumps)
    • 编译器,操作系统和提及架构
  • 作业
    • L5(tshlab):写一个自己的 Unix shell

Virtual Memory

  • 主题
    • 虚拟内存,地址翻译,动态存储分配
    • 体系架构和操作系统
  • 作业
    • L6(malloclab):自己实现 malloc 功能,借此了解系统层次编程

Networking and Concurrency

  • 主题
    • 高层和底层 IO,网络编程
    • Internet 服务,Web 服务器
    • IO Multiplexing with select
    • 网络,操作系统和体系架构
  • 作业
    • L7(proxylab):写一个 web proxy,借此学习网络编程和并行/同步

第一个课的内容大概是这么多,之后会跟着自己学习/课程进度来完成这个系列的文章。

相关文章