Chapter 1: A Tour of Computer Systems 计算机系统之旅
A computer system consists of hardware and systems software that work together to run application programs. Specific implementations of systems change over time, but the underlying concepts do not. All computer systems have similar hardware and software components that perform similar functions. This book is written for programmers who want to get better at their craft by understanding how these components work and how they affect the correctness and performance of their programs.
让我们再次回归这本书的标题,CSAPP——Computer Systems: A Programmer's Perspective,也许在未来我们会选择各式各样的开发方向,也许我们会在不同架构的系统上进行工作,但是许多计算机底层相关的事物在短期内不会动摇。认识到软件是如何在计算机系统下协同工作,对我们成为程序员大有裨益。
在本章中,我们围绕大多数的第一个 C 语言程序 ——helloworld 展开,从一个简单程序的生命周期去观察计算机系统所参与的方方面面
#include <stdio.h>
int main() {
printf("hello world\n");
return 0;
}
2
3
4
5
6
7
当我们在 linux shell 中敲下
linux> gcc -o hello hello.c
计算机系统便执行了上图的流程,我们会在之后的章节中详细地学习每一步。
对于大多数同学而言,运行程序不过是点一个按钮,相信对于大多数同学而言在命令行中敲命令都是极为陌生的体验。实际上,图形化界面也可以看作是对命令的抽象。当你有一些个性化的需求时,命令为你提供更多的参数选择,同时在一些错误发生时,命令的形式有助于你理解到底发生了什么,获取更多信息。这也从侧面体现出底层思维对计算机学习的好处。
回到这个程序的生命周期,类似的疑问也可以是,既然运行一段程序可以是点一个按钮那么简单,为什么我还要了解这其中具体发生了什么。相信各位可以在书中找到答案。
有趣的事实:在 Linux 系统中,硬件也被视为一种文件。这种概念称为 "一切皆文件"(Everything is a file)。在 Linux 中,硬件设备(如磁盘驱动器、键盘、鼠标等)都被表示为文件,可以通过文件系统的方式来访问和操作这些硬件设备。这种文件表示方式使得 Linux 系统能够以统一的方式处理硬件设备和其他文件,提供了一种统一的接口来管理系统资源。
上图的各个结构全书皆有所涉及,重点展开了对我们编程影响较大的部分。
那么当我们执行 hello 的时候,都发生了什么呢。
首先,我们通过键盘输入的指令经过 CPU 处理后传输给主存,此时这条指令仍旧是文本形式。
在处理器完成计算后,程序的结果被存储在磁盘中,得益于一种名为 DMA 的技术(DirectMemoryAccess)磁盘的数据得以直接返回主存。
最后,主存在得到结果之后还需要将数据再次经过 CPU 之手传输回你的图形界面。
观察这个过程,不难发现在这个冗长的过程中,我们的数据经过了漫长的传输路径,对于大部分程序员而言,这是不可见的开销。实际上,在学习相关知识后,这些开销都是可以通过良好的代码减少的。
在计算机中,存储结构就像一座山,越往上,存储空间越小但是越快,越往下,存储空间越大但是越慢。
粗略且直观而言,典型系统上的磁盘驱动器可能比主内存大 1,000 倍,但处理器从磁盘读取一个字所需的时间可能比从内存中读取的时间长 10,000,000 倍。
这意味着,如果我们能让我们的程序更多地使用高效的内存空间,我们程序速度的提升可能比从 O (n^3) 到 O (n^2) 还夸张。我们将在之后的学习中学习这样做的方法和原理。
之前所展示的关于 hello 程序执行的冗长过程可能会让人疑惑,为什么不能让程序直接访问相关硬件呢。
因为这便是操作系统的职责所在,应用程序操作硬件的所有尝试都要经过操作系统。这样做有诸多好处。
The operating system has two primary purposes: (1) to protect the hardware from misuse by runaway applications and (2) to provide applications with simple and uniform mechanisms for manipulating complicated and often wildly different low-level hardware devices. The operating system achieves both goals via the fundamental abstractions shown in Figure 1.11: processes, virtual memory, and files. As this figure suggests, files are abstractions for I/O devices, virtual memory is an abstraction for both the main memory and disk I/O devices, and processes are abstractions for the processor, main memory, and I/O devices. We will discuss each in turn.
出于安全性:阻止软件对硬件不合理的调用。
出于兼容性:硬件种类各式各样,统一的抽象层级和数据格式有利于正确地调用他们。
在本书接下来的部分,我们将粗略了解计算机系统面向软硬件的抽象。
对于每一个进程而言,它被分配到一个处理器(一般情况下独占,但是超线程(Hyper-Threading)技术下可以模拟一个处理器同时处理多个进程(实际上仍是在同一时间点内处理不同的指令流))
获得主存空间一通过给予虚拟内存创造独享主存的假象,这在之后会学到。
数个用于读取的文件,实际上系统级 O 都是给予文件进行的,简洁强大且通用。
在 10-12 章中,我们将学习网络编程的相关内容
网络对于计算机系统而言也可以视作一个硬件,只是访问这个硬件需要额外的规则。
在执行 hello 时,我们可以将执行程序并返回结果这个任务交给网络服务器。
最后,让我们回归这本书的主题,为什么程序员需要了解操作系统的相关内容,假设你的算法占程序的
假设系统的某个部分需要时间的一小部分,并且我们将其性能提高了
加速比为
在上文中,我们大量提到抽象这一概念,那么到底什么是计算机科学中的抽象(Abstract)呢简单而言,抽象就是一个黑箱,你提供输入,它提供输出,对于使用者而言不需要清楚其原理,只需要清楚其功能。同时,在多数时候,使用者并不能直接干涉黑箱的内部运作,这被称为抽象障碍(Abstraction Barrier)用更加程序员的话来说
The use of abstractions is one of the most important concepts in computer science. For example, one aspect of good programming practice is to formulate a simple application program interface (API) for a set of functions that allow programmers to use the code without having to delve into its inner workings. Different programming languages provide different forms and levels of support for abstraction, such as Java class declarations and C function prototypes.
虽然我们不能直接改变操作系统的抽象,但是我们可以根据其原理编写更适应其规则的代码。
事实上,应用软件、硬件、操作系统之间的发展是相辅相成的,三方中一方的新需求与新突破都会为二者带来新发展。
相信看到这里,你已经做好开启一场有趣的计算机之旅的准备。
💡思考题
- 计算机中的一切数据都以二进制的方式存储,那么对于计算机系统而言,它有哪些方法确认数据的格式和解读方式。
- 为什么计算机的存储结构一定是由少量高速与大量低速的存储单元组成的