深入理解计算机系统,第一章:漫游

计算机系统漫游

1.1 信息就是位+上下文

  先看一个简单的Hello World C程序。

1 #include <stdio.h>
2
3 void main()
4 {
5       printf("Hello World!\n");
6 }  

  这个程序的源文件是文本格式,以字节序列的方式存储在文件中,由一种叫ASCII码的方式编码。除了文本文件之外的其它文件都是二进制文件。

  由HelloWorld程序的存储方式可以猜测,信息,包括磁盘文件、内存中运行的程序、内存中储存的用户数据以及通过网络传输的数据,本质上都是一堆bits。区分不同数据的关键在于上下文(context)。在不同的上下文中,同样的字符序列可能代表某个机器指令,或者一个整形数字,或者一个浮点型。

1.2 程序被其它程序翻译成不同格式

  从HelloWorld源程序到可执行程序之间大致经过以下几个阶段:

  #预处理阶段(preprocessor):根据以#开头的宏命令修改原始程序的内容。例如根据#include <stdio.h>将stdio.h的内容插入程序。输出结果还是文本程序。

  #编译阶段(compiler):输出一个汇编语言程序,汇编语言为不同的高级编程语言提供了一种通用的输出语言,这是很有用的。本阶段

输出格式依然是文本文件。

  #汇编阶段(assembly):汇编器将上一阶段的结果翻译成机器语言,生成一个二进制文件称为“可重定位目标程序(relocatable object program)”。

  #链接阶段(linker):由于HelloWorld程序调用了printf函数,而该函数包含在由编译器提供的C标准函数库里面。链接阶段所做的就是将包含printf函数的printf.o文件以某种方式和上一阶段的hello.o合并,结果就得到可执行文件hello,可以被加载到内存中,由系统执行。

1.3 了解编译系统如何工作是大有益处的

  什么是链接错误?While循环和for循环哪个更有效?通过了解编译等方面的知识我们将能回答类似的问题,从而使编程更高效。

1.4 处理器读取并解释存储在内存中的命令

  一个典型的系统由哪些硬件组成?

  #总线(bus):总线负责信息在各个部件之间的传递。信息在总线中以定长的方式传递,也就是字(word)。字中的字节数是系统的基本参数之一。大多数机器的字长是4个字节(32位),有的机器字长是8个字节(64位)。

  #输入输出设备(I/O):输入输出设备是系统与外界联系的通道。通常一个I/O设备不是适配器(adapter)就是控制器(controller),区别在于adapter是插到卡槽中的,而controller是I/O设备本身或主板上的芯片组。比如显示设备是adapter,而键盘鼠标和硬盘则是controller。在系统的角度来说,网络(network)也是一种I/O。

  #主存(main memory):主存是一个临时储存设备,在处理器执行程序时用来储存程序和程序的数据。

  #处理器(CPU):中央处理单元,简称处理器,是解释存储在主存中指令的引擎。从系统通电开始,到系统断电,处理器一直在不断的执行计数器(PC)指向的指令,再更新计数器,使其指向下一条指令。CPU的操作是围绕主存、寄存器文件(register file)、ALU进行的。寄存器文件是一个小的存储设备,由一系列1字长的寄存器组成,每个存储器都有唯一的名字。ALU(算数/逻辑单元)计算新的数据和地址值。CPU在指令的要求下可能执行以下动作:、

    ~加载:把一个字节或一个字从主存复制到寄存器,以覆盖寄存器原来的内容。

    ~存储:把一个字节或一个字从寄存器复制到主存的某个地方,以覆盖这个地方原来的内容。

    ~操作:把两个寄存器的内容复制到ALU,对这两个字进行算数操作,并将结果存在一个寄存器中,覆盖原来的内容。

    ~跳转:从指令中取出一个字,并将这个字复制到程序计数器(PC)中,覆盖原来的内容。

1.5 高速缓存至关重要

  一个典型系统上的磁盘可能比主存大一千倍,但是从磁盘读取数据的速度可能比从主存读取数据的速度慢一千万倍。处理器从主存中读取文件的速度比从主存中读取的速度又快了几乎一百倍。而且让处理器运行的更快比让主存运行的更快要便宜的多。针对这种情况,系统设计者采用了更小、更快速的存储设备,也就是告诉缓存。L1缓存运行最快,但是容量最小。L3缓存运行较慢,但是容量较大。这些缓存的读取速度都比主存快很多。意识到高速缓存存在的程序员能够利用它们使得程序的性能大大提升。

1.6 存储设备层次结构

  在存储器的层次结构中,CPU寄存器位于顶端,其次是三级缓存,然后是主存、本地磁盘,甚至是远程存储。存储器的层次结构的主要思想是上一级的存储器作为下一集的存储器的高速缓存。例如,寄存器是L1的高速缓存,L1-L3则是主存的高速缓存,主存则是硬盘的高速缓存。程序员同样可以利用队存储器层次结构的理解来提高程序的性能。

1.7 操作系统管理硬件

  应用程序不会直接访问I/O和主存等设备。它们依靠操作系统提供的服务。我们可以把操作系统看做是应用程序和硬件之间的一层软件。应用程序对硬件的所有操作尝试都必须经过操作系统。

  操作系统有两个基本功能:

    1、防止硬件被失控的程序滥用。

    2、为应用程序提供简单一直的机制来控制复杂多变的底层硬件设备。

  操作系统通过一系列抽象来完成目标。文件是对I/O设备的抽象。虚拟存储器是对主存、磁盘存储器的抽象。进程(process)是对处理器、I/O和存储器的抽象。

  进程是计算机对一个应用程序的一种抽象,在一个系统上可以同时运行多个进程,每个进程都好像在独占硬件。并发运行,说的是一个进程的指令和另一个进程的指令是交错执行的。操作系统在不同的进程中保存各自的上下文(context),这种交错执行的机制称为上下文切换。

  在现代系统中,一个进程实际上可以由多个称为线程的执行单元组成。每个线程都运行在进程的上下文中,共享同样的代码和全局数据。

  虚拟存储器是一个抽象概念,它为每一个进程提供了一个假象,即每个进程都在独占的使用内存。每个进程看到的是一致的存储数据,称为虚拟地址空间。下图是Linux进程的虚拟地址空间。

  注意地址从下往上逐渐增大。

    #程序代码和数据:对所有进程来说,代码从同一固定地址开始。代码和数据区按照可执行目标文件的数据来进行初始化。

    #堆(heap):代码和数据区在程序运行时就规定了大小,而堆则可以在运行时动态的收缩,如调用malloc和free等时。

    #共享库(shared libiaries):存放C标准库和数学库等共享库的地方。

    #栈(stack):编译器用它来实现函数调用。栈的大小也是运行期动态收缩的。当我们调用一个函数它就增大,函数返回时它就收缩。

    #内核虚拟存储器(kernel virtual memory):内核总是在内存中,是操作系统的一部分。顶部区域是为内核保留,不允许应用程序使用或直接调用内核中定义的函数。

  虚拟存储器的基本思想是把一个程序的虚拟存储器的内容存储在磁盘上,然后使用主存作为磁盘的高速缓存。

  文件就是字节序列。每个I/O设备,包括磁盘、键盘鼠标、显示器,甚至网络,都可以看做文件。文件响应用程序提供了一个统一的视角来看待各种不同的I/O设备。程序可以不关系具体的磁盘技术而处理磁盘文件内容,同一个程序可以在使用不同磁盘技术的不同系统上运行。

1.8 系统之间利用网络通信

  系统通过网络和其它系统连接在一起。在单独的系统来看,网络可以视为一个I/O设备。

1.9 重要主题

  并发并行。术语并发(concurrency)指的是同时具有多个活动的系统。并行(parallelism)指的是用并发使系统运行的更快。

    #线程级并发:使用线程,我们能够在一个线程中执行多个控制流。传统意义上的并发还是快速在多个正在执行的进程中切换来实现的。由一个处理器来进行运算的系统称作单处理器系统。由但操作系统内核控制的多处理器系统称为多处理器系统。实现多处理器系统可以通过多核(multi-core)或超线程(hyper-threaded)。

    多核处理器是将多个CPU(称为“核”)集成到一个集成电路芯片上。

    超线程,是一项允许一个CPU执行多个控制流的技术。它涉及CPU某些硬件具有多个备份,如PC和寄存器;而其他硬件只有一份,如执行浮点算数运算的单元。常规处理器大约需要2000个clock cycle来执行不同线程之间的转换,而超线程的处理器可以在单个周期的基础上决定要执行哪个线程。如果一个核可以执行两个线程,那么一个四核的系统可以并行的执行8个线程。

    #指令级并行

    在较低的抽象层级上,现代处理器可以并行的执行多条指令,称为指令级并行。如果一个处理器可以达到比一个周期一条指令更快的操作,那么久称为超标量(superscalar)处理器。大多现代处理器都支持超标量操作。

    #单指令、多数据并行

    在最低层次上,许多现代处理器拥有特殊硬件,允许一条指令产生多个可以并行执行的操作,称为单指令、多数据。

1.10 小结

  计算机内部的信息被表示为一组组的位,他们依据上下文有不同的解释方式。程序被其它程序翻译为不同的形式,最开始是ASCII文本,然后被编译器和链接器翻译成二进制可执行文件。

  处理器读取并解释存放在主存里的二进制指令。因为计算机花费大量时间用来在存储器、I/O设备和CPU寄存器之间复制数据,所以将系统中的存储设备划分成层次结构——寄存器在顶部,然后是高速缓存、主存和磁盘。在存储器层次结构中,位于更高位置的存储器比低层位置的存储器更快,单位比特的开销也更高。较高层次的存储设备为较低层次的存储设备提供高速缓存。

  操作系统内核是硬件和应用程序之间的抽媒介。它提供了三个基本抽象:文件是I/O设备的抽象,虚拟存储器是对主存和磁盘的抽象,进程是对处理器、主存和I/O设备的抽象。

  网络提供了计算机系统间的通讯手段。从单个系统的角度看,网络就是一种I/O设备。

    

时间: 2024-12-29 07:09:06

深入理解计算机系统,第一章:漫游的相关文章

深入理解计算机系统第一章

第一章 计算机系统漫游在unix系统中 从源文件到目标文件的转化室由编译器驱动程序完成的linux > gcc -o hello hello.c 编译得过程预处理器,编译器,汇编器,链接器 原文地址:https://www.cnblogs.com/DreamKill/p/12274999.html

CSAPP深入理解计算机系统第二章荟萃

1.可以利用数字的算数右移,然后利用0XFF这样的数字做掩码运算,可以获取到一个数字的符号位.计算机的移位运算有一种很重要的作用就是利用掩码运算去提取一个位模式的一段信息. 2.在C语言中的条件语句,以及三目的条件运算符,都可以用移位的方式来做. 3.在进行位扩展操作的时候,比较讲一个32位的有符号数扩展到64位,那么在保证原来的值不变的情况下,把31个低位扩展到64位的低位上,而最高的符号位扩展到高33位上. 4.利用位模式仅仅只能表示一些2的n次幂的一些浮点数,其他的比较特殊的有理数,会近似

深入理解计算机系统 第二章 信息的表示和处理

欣哥划重点: @所有人, 第二章比较难,我建议至少掌握下面几个知识点: 1. 字节顺序 : 大端和小端 2. 运行 图2-24, 图2-25程序 show-bytes.c 观察结果,看看有什么问题 3. 理解布尔运算,位运算 4. 理解无符号数和有符号数, 给一个数,能计算出补码 5. 理解浮点数的表示法,给一个十进制小数,能转换成二进制的浮点数表示 原文地址:https://www.cnblogs.com/stone94/p/9824395.html

深入理解计算机系统-第二章

疑惑: ***."十进制数字x的ASCII码正好是0x3x"(p31) ```.照上面这么说,十进制1的ASCII码该是0131,很明显错误的,找到一个ASCII码来看下"1"的ASCII码是"49", 再仔细参考下书中上下文,发现上面说了十进制1的ASCII码是31,那原句这么说"十进制数字_x的ASCII码正好是0x3_x"是不是更好理解点, 避免"x"的理解错误,你可能又会说,现在还是不对啊,现在1的

深入理解计算机系统 第二章要点

1.每台机器都有一个字长,指明了整数和指针的标称大小(normal size),长整数(long int)和指针的大小都是字长(32位机器是32位,64位机器是64位),字长代表了机器的寻址时地址大小,进而限定了寻址空间的大小,字长w的寻址范围是0-2的(w-1)次方,32位机上线是4G.除了和字长同步的类型(long int和指针)其他类型大小和机器无关,比如char,short,int4,long long int8, float4, double8在32位机器上对8字节的类型数据操作时,先

深入理解计算机系统 第二章 信息的表示和处理 part2

上一周遗留问题的解决 问题:原码.反码.补码是只针对有符号数吗?无符号数有没有这三种编码方式? 得到的答案:对于无符号数,原码.反码和补码是一致的 进一步,由于有符号数是以补码的形式存储在计算机中的,而无符号数三种编码都是一致的,所以我们可以说,整型数在计算机中是以补码的形式存在的. 参考文章: https://www.jianshu.com/p/ffc97c4d2306 浮点数 对于浮点数,看了刘大的文章<看完这篇文章,你肯定理解什么是浮点数了>之后,知道了两点 1.浮点数是如何存储的 2.

深入理解计算机系统第二章家庭作业

*2.91遵循位级浮点编码规则,实现具有如下原型的函数: /* Compute |f|. If f is NaN ,then return f. */ float_bits float_absval (float_bits f); 对于浮点数f,这个函数计算|f|.如果f是NaN,你的函数应该简单地返回f. 测试你的函数,对参数f可以取的所有2^32个值求值,将结果与你使用机器的浮点运算得到的结果相比较. 解题过程 ****2.95遵循位级浮点编码规则,实现具有如下原型的函数: /* Compu

深入理解计算机系统 第二章答案

http://rooftrellen.com/blog/computer-systems-a-programmers-perspective-chapter-2-homework-problem/

读《大道至简》-第一章之感想

上了一节JAVA课.课上,老师是从<大道至简>开始讲课的,虽然我之前没看过,但是大概知道了主要内容.但是,具体的问题我还真心的回答不上来.比如,愚公移山的分析,编程的根本.靠着自己的这一遍阅读和听着老师讲解才能理解了第一章.    我觉得愚公移山的故事,虽然可以告诉我们编程的过程和本质.但是总是觉得,人家分析的虽不能太过牵强,但是的确是套用的.其实,我们生活的每一件事都可以反映编程,也不一定要特别刻板的去找愚公移山的故事.生活中的每一件事都可以分为两个步骤,这两个步骤其实就是编程里的认识需求以

深入理解计算机系统读书笔记之第一章:漫游

我是从豆瓣上看到好多人都在推荐这本书,于是就去借来读一读,昨天晚上用了好长时间来读这本书的第一章节,感觉这本书比较符合我(有些基础还不太明白,这本书详细的进行了讲解,很好). 下面写一下我的理解(顺便回顾一下知识) 第一节主要讲的是: A Tour of Computer Systems 以hello.c为例进行讲解,介绍这个程序如何从一个源程序变成可执行程序,再到执行,显示屏上出现“hello,world” ···········································