深入理解计算机系系统
计算机系统漫游
第一章给人的感觉是什么都讲了一些,但讲的都太过浅显,跳跃性太大。
一些概念
- 可重定位目标程序:汇编器将汇编语言处理成的格式。
- 可执行目标文件:链接库函数之后,得到的文件(可执行文件)
- 多核处理器:多个CPU集成到一个电路芯片上,共享主存和其他资源
- 超线程:同时多线程,由于模拟并发,并行的切换使得机器无法在单位时间内处理超过一个线程,除非至少有两个物理概念上的CPU,于是超线程技术仅保留部分必须的独立资源(程序计数器和寄存器文件等),其余资源共享,使得多个线程可以同时执行,如果要求使用的资源冲突,应该也是无法同时执行的。
- 指令级并行:即指令流水,一个指令需要多个阶段。这些不同阶段可以由不同的部件执行,将一条指令拆解成更细的单元,使得指令可以同时执行,只要不处于同一阶段。
- 超标量:处理器达到比一个周期一条指令更快的执行速率
- 单指令,多数据并行:一个控制器控制多个运算器,使得两组数据可以同时执行相同的指令。
- Amdahl定律:当我们系统的某个部分加速时,其对系统整体性能的影响取决于该部分的重要程度和加速程度。要想显著的加速整个系统,必须提升全系统中相当大部分的速度。
一个问题
hello.txt文件和hello.c文件都是ascii字符,文本文件,底层都是相同的01序列,为何可以编译c文件不能txt文件
试验:写一个hello.txt的python代码,可以被python编译器识别,执行,但是无法被c语言编译器执行
猜测:c语言编译器附加有对文件名的识别
重要过程
源程序到目标文件的转化
-
预处理( h e l l o . c hello.c hello.c— h e l l o . i hello.i hello.i)
从文本文件到文本文件,由预处理器操作
- 处理#开始的指令(详细内容在程序员的自我修养)
- 删除所有注释,将其替换成空格(这一点C primer plus有所提及)
- 添加行号和文件名标识,以便于编译时编译器调试
- 保留**#pragma**指令,编译器需要使用它们
-
编译( h e l l o . i hello.i hello.i— h e l l o . s hello.s hello.s)
从文本文件到文本文件,由编译器操作
将其编译成一个汇编语言文本文件(编译具体过程,应是编译原理的内容)
-
汇编( h e l l o . s hello.s hello.s— h e l l o . o hello.o hello.o)
从文本文件到二进制文件,由汇编器操作
每一条汇编语句几乎都对应一条机器指令,因此汇编器根据对照表翻译即可
汇编器将翻译的机器指令按照可重定位目标程序的格式打包,并保存在 h e l l o . o hello.o hello.o中
-
链接( h e l l o . o hello.o hello.o– h e l l o hello hello)
h e l l o . c hello.c hello.c调用了库函数,这个库函数早就被提前编译好,得到 h e l l o . o hello.o hello.o后,必须将其整合到我们的文件里面,这个过程就是链接。
链接之后就被装入到内存执行。
虚拟地址空间
主存,硬盘被抽象成一个虚拟的存储器,也就是虚拟地址空间
从低地址到高地址依次是:
程序代码和数据,堆,共享库,栈,内核虚拟内存