CMU 15-213(513) Introduction to Computer Systems (24Fall) 总结

课程总述

CMU的校友课,有意思的是本科生课号15213也是CMU的邮编。里面的Lab十分经典,之前上课的两位老师也是著名的 CSAPP (Computer Systems: A Programmer’s Perspective) 一书的作者。因为项目比较偏 System ,很多 System Core 的必修课 (例如 Distributed System 以及 三选一的系统核心课)还有大名鼎鼎的 ACC (Advanced Cloud Computing) 等 都要求513的先修课要求。这门课主要有以下几个部分:计算机底层数据以及 GDB 的使用(Data Lab, Bomb Lab, Attack Lab);内存管理(Cache LabMalloc Lab);进程与异步(Shell Lab, Proxy Lab, SFS Lab)。类似于 Berkeley 在CS 61C 中提供的 Hive Machine,CMU 也提供了 Shark Machine 来提供配置环境。我们通过 VS Code SSH 进行连接即可。

课程成绩 (95.17% -- A)

这门课的 Lab 占了很大的比重 (50%),并且 Lab 比较强调代码规范性,每一个 Lab 都会有 Code Review,其中检查了 Function Header, File Header 以及在 官网 Code Style 中还包含的如 Magic Number之类的 Code Smell。期末考试3个小时时间其实满打满算基本用完了。

课程内容

因为 15513 并没有给 Master Student 排课, 要么去蹭 15213 的课 (但因为现在不是 CSAPP 的作者在上课了所以意义也不是很大),要么听 14513 的回放;所以更多的是去每周 TA 组织的 Recitation,以及听 B站up主 九曲阑干对 CSAPP 的讲解 。 这里主要是结合 Lab 对课程内容的感受。

  • Data Lab: 只能通过最简单的 bitwise operations (&, |, ^ , ~, << , >>),而不允许使用一般的运算符( +,-,*,/等)来完成数据的复杂操作。里面稍微难一点的内容还涉及到了递归操作。除了正确性意外,对于一个要实现的函数有着最大字符数的限制。最后在正确性的基础上根据使用的字符数在 Auto Lab 进行排名。
  • Bomb Lab:从这里开始就引入了汇编以及通过 GDB 来与程序进行交互。主要逻辑就是在每一个 Stage 需要去输入密文 (这个密文其实是通过密码校验的汇编代码来进行破解获取的,所以我们一开始只需要随便输入一个密文,而需要关注在后续这个密文是如何被处理的),密文如果输入错误就会触发 Bomb 函数从而导致被扣分。所以一开始一定要在 Bomb 函数的起始位置打上 Break Point,这样即便触发了这个函数,也会在它起始位置停下,然后我们直接 quit 掉整个程序进程即可。不过不得不说纯 GDB 来看汇编代码确实会比较累,后面在 Secure Coding 学会了安装 Peda 等插件来进行更好的寄存器、栈等内容的可视化。
  • Attack Lab: 比较简单的一个 Lab,和做 CTF 差不多。包括了 Stack Overflow, 构造可执行代码,以及 ROP (Return Oriented Programming)等内容。
  • Cache Lab: 从这里开始需要写完整的C代码了。这个 Lab 分为两个部分,第一个就是实现一个 Write Back (也就是更新后的脏数据不会直接写入内存中,而是只有当被 evicted 的时候才会写回到内存) 的 Cache,同时实现 LRU (Least Recently Used) 的 eviction policy,第二个需要通过 block technique 来对二维数组的操作 (如转置等)进行优化。
  • Malloc Lab: 实现一个简单的 Memory Manager。包含了实现 malloc, free, realloc 等操作。这个 Lab 的关键在于优化两个指标: utilization 以及 throughput。从而需要对实现的 Memory Manager 进行不断地优化 (例如从 implicit list 到 explicit list, 再到 segregated list, 后面还需要优化header footer等内容,在我的另一个blog中有更详细的介绍)。这个 Lab 有两个 checkpoint,第一个在完成 throughput 优化的基础上需要实现 heap checker,也就是检查堆中分配的内存需要符合我们的预期。
  • Shell Lab: 实现一个简单的 Shell (包含 foreground 进程以及 background 进程)。分为了很多个 trace 来验证这个 shell 所能够处理的内容 (比如sigint, sigkill, sigchild等);最后还包括了 IO redirection,在掌握 File Descriptor Table 和 Open File Table 的关系后提供 dup2 等操作来进行处理。。
  • Proxy Lab: 实现一个 client 和 server 端的代理。需要解析处理 client 发送的 request line, request header,以及处理之后发送给 server 端,再收到 server 端返回的 response line 和 response header 之后再进行处理返回给 client 端。这里的 proxy 其实还可以实现 cache 等操作。在第二部分中通过 pthread_create 等函数来实现了多线程处理。
  • SFS Lab: 这里的 Secure File System 中的 Secure 主要指的是多线程安全。在第一部分中我们只需要实现单线程基础上的 readseek, rename 等函数。而对于多线程,我们需要考虑如何对不同粒度的锁来保证性能更高但是不会引发竞争或者死锁的问题。

课程感受

作为CMU校友课,这门课也几乎是所有 15 (SCS 代码前缀) system 课程的 prerequsite 课程。这门课的 Lab (除了 SFS Lab) 已经经过了很多年的打磨,已经很经典。并且这门课确实是作为 CMU 学术 rigor 的体现。它禁止作业,Lab 使用一切外部辅助资料 (如 AI 等),否则就是 Academic Integrity Violation 这门课直接会挂掉并且受到学业警示。并且这里的 Lab 相对于 Berkeley CS 课程的 Lab 一个很鲜明的区别就是:CMU的 Lab 一般就是给你一个很长的 PDF 文档,往往做实验都需要你一步一步去做并且再优化,最后在完成的基础上再进行测试; 而 Berkeley CS Lab 一般都是有公开的而且做得比较好的网页,每一步都有对应的函数和明确的目标,再完成这一步之后就可以得到这一步的分。而513的 Shell Lab 虽然也是这样,但是因为是在同一个函数进行实现所以即便通过了后面的 trace ,但前面的 trace 又 fail 掉了。总的来说 CMU 这边的课程也确实有挑战性。