深入理解计算机系统:第1-2章

第1章 计算机系统漫游

图1 编译系统

GCC(GNU Compiler Collection)

预处理 -E
只执行到预编译,默认输出至控制台
gcc -E main.c -o main.i

编译 -S
只执行到编译,默认生成汇编文本文件,后缀.s
gcc -S main.i
gcc -S main.c

汇编 -c
只执行到汇编,默认输出二进制目标文件,后缀.o
gcc -c main.s
gcc -c main.c

链接
生成可执行文件
gcc main.o -o main
gcc main.c -o main
// 自动优化编译
gcc -O main.c -o main


程序编译

预处理: 加载头文件至原始程序;
编译: 编译器将文本文件hello.i翻译成汇编程序文本文件hello.s;
汇编: 汇编器将汇编程序文件翻译成机器语言指令;
链接: 链接将已经编译好的目标文件(后缀.o)合并,生成可执行文件;


程序运行

获取指令: 键盘输入"./hello",字符读入寄存器,再存放至内存;
加载文件: 利用直接存储器存取技术(DMA),目标文件可不通过CPU直接从磁盘加载到主存;
程序执行: 机器指令从主存复制到寄存器并执行,执行结果从寄存器复制到显示设备,打印输出;


高速缓存cache

内存读取速度比磁盘读取快约1000万倍;
寄存器读取速度比主存读取快约100倍;
高速缓存L1和L2是一种静态随机访问存储器(SRAM)。L1高速缓存读取速度约等于寄存器,比L2高速缓存快5倍; L2高速缓存读取速度比主存读取快5~10倍;


操作系统

基本功能

防止硬件被失控的程序滥用;
向应用程序提供简单一致的机制控制复杂的低级硬件设备;
注:基于进程、虚拟内存、文件实现

进程

进程是操作系统对正在运行的程序的一种抽象。
并发运行是指一个进程的指令和另一个进程的指令交错执行,多个进程同时活动。一个CPU通过上下文切换实现并发执行多个程序。

线程

一个进程由多个线程组成,每个线程都运行在进程的上下文中,共享同样的代码和数据。

虚拟内存和虚拟内存空间

虚拟内存是主存和I/O设备的抽象,它为每个进程提供一种独立占用内存的假象。
每个进程看到的内存都是一致的,称为虚拟地址空间。
虚拟地址空间包括:只读的代码和数据、读/写数据、堆、共享库、栈、内核虚拟内存。

文件

文件就是字节序列,每个I/O设备,包括磁盘、键盘、显示设备,甚至网络都可看为文件。

并发与并行

并发是同时具有多个活动的系统,并行是用并发使系统运行的更快。

线程级并发: 超线程,又称为同时多线程,允许单CPU执行多个控制流的技术;

指令集并发: 早期处理器需3~4个机器周期处理一条指令,现在CPU利用流水线技术,将一条指令划分为不同步骤。这些阶段可并行操作,用来处理不同指令的不同部分。若处理器一个机器周期可执行一条以上的指令,称之为超标量处理器。

单指令、多数据并行: 特殊的硬件结构允许一条指令产生多个并行执行的操作,称之为单指令、多数据(SIMD)并行。如并行对8对单精度浮点数做加法。



第2章 信息的表示和处理

2.1 信息存储

字长

字长指明指针数据的标称大小,虚拟地址以一个字长编码。字长决定了最大的寻址空间,即决定了虚拟地址空间的有效值。
如对于32位计算机,最大寻址空间 2 32   b y t e s = 4   G B \sf{2^{32}\,bytes = 4\,GB}

寻址和字节顺序

大端/小端法分别以最高/最低有效字节在最前面(地址较小)的方式存储数据。
假设 i n t \sf{int} 型变量 x \sf{x} 位于地址 0 x 100 \sf{0x100} 处,其十六进制值为 0 x 12345678 \sf{0x12345678} ,以大端法和小端法的存储格式分别如下:

移位运算

逻辑右移左端补0,算数右移左端补符号位。
如有符号数-8,补码表示为1111 1000,算数右移1位(等价于除2),得到1111 1100,即-4。


2.2 整数表示

编码

对向量 x = [ x w 1 , x w 2 ,   , x 0 ] \vec x=[x_{w-1},x_{w-2}, \cdots, x_0] ,则位向量到整数的映射

无符号编码( b i n a r y   t o   u n s i g n e d \sf{binary \, to \, unsigned} ):
B 2 U w ( x ) = i = 0 w 1 x i 2 i B2U_w(\vec x)=\sum_{i=0}^{w-1} x_i2_i

反码编码( b i n a r y   t o   t w o s   c o m p l e m e n t \sf{binary \, to \, two's \,complement} ),正数反码与原码相同,负数反码是对其原码除符号位逐位取反,则:
B 2 O w ( x ) = x w 1 ( 2 w 1 1 ) + i = 0 w 2 x i 2 i B2O_w(\vec x)=-x_{w-1}(2^{w-1}-1) + \sum_{i=0}^{w-2} x_i2_i

补码编码( b i n a r y   t o   t w o s   c o m p l e m e n t \sf{binary \, to \, two's \,complement} ),正数补码与原码相同,负数补码为其补码加1,则:
B 2 T w ( x ) = x w 1 2 w 1 + i = 0 w 2 x i 2 i B2T_w(\vec x)=-x_{w-1}2^{w-1} + \sum_{i=0}^{w-2} x_i2_i

类型转换

对整数 x x ,其向量表示 x = [ x w 1 , x w 2 ,   , x 0 ] \vec x=[x_{w-1},x_{w-2}, \cdots, x_0] ,有以下转换:

补码转为无符号数
B 2 U w ( x ) B 2 T w ( x ) = x w 1 2 w B2U_w(\vec x) - B2T_w(\vec x)=x_{w-1}2^w ,且 B 2 T w ( x ) = x B2T_w(\vec x)=x ,得 B 2 U w ( x ) = x w 1 2 w + x B2U_w(\vec x)=x_{w-1}2^w+x ,得
T 2 U w ( x ) = B 2 U w ( x ) = x w 1 2 w + x T2U_w(x)=B2U_w(\vec x)=x_{w-1}2^w+x

无符号数转为补码
B 2 U w ( x ) B 2 T w ( x ) = x w 1 2 w B2U_w(\vec x) - B2T_w(\vec x)=x_{w-1}2^w ,且 B 2 U w ( x ) = x B2U_w(\vec x)=x ,得 B 2 T w ( x ) = x x w 1 2 w B2T_w(\vec x)=x-x_{w-1}2^w ,得
U 2 T w ( x ) = B 2 T w ( x ) = x x w 1 2 w U2T_w(x)=B2T_w(\vec x)=x-x_{w-1}2^w

C语言中有符号数与无符号数运算时,有符号数会强制转为无符号数,比较大小时可能出错!负值赋给无符号数,自动执行T2U转换。

short v1 = -12345;
unsigned short u = (unsigned short)v1;
short v2 = (short)u;
cout << u << ' ' << v2 << endl;
//53191 -12345

// 无符号数与有符号数计算,有符号数会强制转为无符号数
unsigned int a = 0;
int b = -1;
cout << (a > b) << endl;
// 0
// 无符号数溢出
cout << a - 1 << endl;
// 4294967295

位扩展与截断

无符号数扩充位使用零扩展,补码数扩充位使用符号扩展。
位扩展时,先转换大小再转换符号,如short v = -12345,则(unsigned)v = 4294954951。
无符号数截断时,丢弃截断位;补码数截断时,丢弃截断位并将结果进行 U 2 T k U2T_k 转换。

short v = -12345;
unsigned u1 = v;
unsigned u2 = (unsigned)(int)v;
unsigned u3 = (unsigned)(unsigned short)v;
cout << u1 << ' ' << u2 << ' ' << u3 << endl;
// 4294954951 4294954951 53191
cout << (short)u1 << ' ' << (short)u2 << ' ' << (short)u3 << endl;
// -12345 - 12345 - 12345

int v1 = (1<<16) + (1<<15);
cout << short(v1) << endl;
// -32768


2.3 整数运算

无符号数加法
x &ThinSpace; + w u &ThinSpace; y = { x + y , x + y &lt; 2 w x + y 2 w , x + y 2 w x \, +_w^u \, y= \begin{cases} x+y, &amp; \text x + y &lt; 2^w &amp; \quad正常\\ x + y - 2^w, &amp; \text x+y \geq 2^w &amp; \quad溢出 \end{cases}

补码加法
x &ThinSpace; + w t &ThinSpace; y = { x + y 2 w , x + y 2 w 1 x + y , - 2 w 1 x + y &lt; 2 w 1 x + y + 2 w , x + y &lt; 2 w 1 x \, +_w^t \, y= \begin{cases} x+y-2^w, &amp; \text x + y \geq 2^{w-1} &amp; \quad正溢出 \\ x + y, &amp; \text -2^{w-1} \leq x +y &lt; 2^{w-1} &amp; 正常 \\ x+y+2^w, &amp; \text x+y&lt; -2^{w-1} &amp; \quad负溢出 \end{cases}

无符号数乘法
x w u y = ( x y ) m o d &ThinSpace;&ThinSpace; 2 w x *_w^u y = (x \cdot y) \mod 2^w

补码乘法
x w t y = U 2 T w ( ( x y ) m o d &ThinSpace;&ThinSpace; 2 w ) x *_w^t y = U2T_w((x \cdot y) \mod 2^w)

无符号和补码乘法的位级等价性
x = T 2 U w ( x ) = x + x w 1 2 w x&#x27;=T2U_w(x)=x+x_{w-1}2^w y = T 2 U w ( y ) = y + y w 1 2 w y&#x27;=T2U_w(y)=y+y_{w-1}2^w ,故
( x y ) m o d &ThinSpace;&ThinSpace; 2 w = [ ( x + x w 1 2 w ) ( y + y w 1 2 w ) ] m o d &ThinSpace;&ThinSpace; 2 w = [ x y + ( x w 1 y + y w 1 x ) 2 w + x w 1 y w 1 2 2 w ] ) m o d &ThinSpace;&ThinSpace; 2 w = ( x y ) m o d &ThinSpace;&ThinSpace; 2 w \begin{aligned} (x&#x27; \cdot y&#x27;) \mod 2^w &amp; = [(x+x_{w-1}2^w) \cdot (y+y_{w-1}2^w)] \mod 2^w \\ &amp; = [x\cdot y + (x_{w-1}y+y_{w-1}x)2^w+x_{w-1}y_{w-1}2^{2w}]) \mod 2^w \\ &amp; = (x \cdot y) \mod 2^w \end{aligned}
带权重 2 w 2^w 2 2 w 2^{2w} 的项取模运算均为0。

乘法优化
整数乘法指令相当慢,约10个机器周期,一般分解为加法、减法、位级运算和移位运算。
对于乘法x*K,K的二进制是一组0和1交替的序列,如14可写为[0…01110]。
考虑一组从位置n到m的连续1(对于14,n=3,m=1),可用下列方式计算乘积:
\quad 形式A:(x << n) + (x << (n-1) + ··· + (x << m))
\quad 形式B:(x << (n + 1) - (x << m))
如x * 14 = (x << 4) - (x << 1),只需要两次移位和一次减法。

整除舍零偏置

整数除法比整数乘法更慢,约30个机器周期。
向下舍入: 对于任意实数a,定义 a \lfloor a \rfloor 为唯一整数a’,使得 a a &lt; a + 1 a&#x27; ≤ a &lt; a&#x27; + 1
3.14 = 3 \lfloor 3.14 \rfloor=3 3.14 = 4 \lfloor -3.14 \rfloor=-4

向上舍入: 对于任意实数a,定义 a \lceil a \rceil 为唯一整数a’,使得 a 1 a &lt; a a&#x27;-1 ≤ a &lt; a&#x27;
3.14 = 4 \lceil 3.14 \rceil = 4 3.14 = 3 \lceil -3.14 \rceil = -3

向上舍入与向下舍入的关系: x / y = ( x + y 1 ) / y \lceil x/y \rceil=\lfloor (x+y-1)/y \rfloor
证明:令 x = q y + r x=qy+r ,其中 0 r &lt; y 0\leq r &lt; y ,则 ( x + y 1 ) / y = q + ( r + y 1 ) / y \lfloor (x+y-1)/y \rfloor=q+\lfloor (r+y-1)/y \rfloor 。当 r = 0 r=0 时, x / y = q \lceil x/y \rceil=q ;当 r &gt; 1 r&gt;1 时, x / y = q + 1 \lceil x/y \rceil=q+1 。因此,实现了向上舍入。

除以2的幂除法(右移)

无符号除法(向下舍入): 对于无符号数 x w x_w k k ,且 0 k &lt; w 0 \leq k &lt; w ,则逻辑移位 x &gt; &gt; k = x / 2 k x &gt;&gt; k = \lfloor x/2^k\rfloor
证明:
x = [ x w 1 , x w 2 , &ThinSpace; , x 0 ] x=[x_{w-1},x_{w-2},\cdots,x_0] x = [ x w 1 , x w 2 , &ThinSpace; , x k ] x&#x27;=[x_{w-1},x_{w-2},\cdots,x_k] x = [ x k 1 , x k 2 , &ThinSpace; , x 0 ] x&#x27;&#x27;=[x_{k-1},x_{k-2},\cdots,x_0] ,其中 x x x x&#x27; x x&#x27;&#x27; 均为无符号数。
x = 2 k x + x x=2^kx&#x27;+x&#x27;&#x27; 0 x &lt; 2 k 0 \leq x&#x27;&#x27; &lt; 2^k ,得 x &gt; &gt; k = x / 2 k = x x&gt;&gt;k= \lfloor x/2^k\rfloor=x&#x27;

补码除法(向下舍入): 对于补码 x w x_w 和无符号数 k k ,且 0 k &lt; w 0 \leq k &lt; w ,则算术移位 x &gt; &gt; k = x / 2 k x &gt;&gt; k = \lfloor x/2^k\rfloor
证明:
x = [ x w 1 , x w 2 , &ThinSpace; , x 0 ] x=[x_{w-1},x_{w-2},\cdots,x_0] x = [ x w 1 , x w 2 , &ThinSpace; , x k ] x&#x27;=[x_{w-1},x_{w-2},\cdots,x_k] x = [ x k 1 , x k 2 , &ThinSpace; , x 0 ] x&#x27;&#x27;=[x_{k-1},x_{k-2},\cdots,x_0] ,其中 x x x x&#x27; 为补码数, x x&#x27;&#x27; 为无符号数。
则与无符号数类似,有 x = 2 k x + x x=2^kx&#x27;+x&#x27;&#x27; 0 x &lt; 2 k 0 \leq x&#x27;&#x27; &lt; 2^k ,得 x &gt; &gt; k = x / 2 k = x x&gt;&gt;k= \lfloor x/2^k\rfloor=x&#x27;

补码除法(向上舍入): 对于补码 x w x_w 和无符号数 k k ,且 0 k &lt; w 0 \leq k &lt; w ,则算术移位 ( x + ( 1 &lt; &lt; k ) 1 ) &gt; &gt; k = x / 2 k (x +(1&lt;&lt;k)-1)&gt;&gt; k = \lceil x/2^k\rceil
证明:
x / y = ( x + y 1 ) / y \lceil x/y \rceil=\lfloor (x+y-1)/y \rfloor ,令 y = 2 k y=2^k ,得 ( x + 2 k 1 ) / 2 k = x / 2 k \lfloor (x+2^k-1)/2^k \rfloor=\lceil x/2^k\rceil
( x + ( 1 &lt; &lt; k ) 1 ) &gt; &gt; k = x / 2 k (x +(1&lt;&lt;k)-1)&gt;&gt; k = \lceil x/2^k\rceil


2.4 浮点数

IEEE浮点表示

V = ( 1 ) s × M × 2 E V=(-1)^s \times M \times 2^E

符号s决定正负数;尾数M是二进制小数,范围是 1 2 ϵ 1 \sim 2- \epsilon 1 1 ϵ 1 \sim 1 - \epsilon 阶码E用于对浮点数加权。

对于单精度32位浮点数,符号s占1位、阶码占k=8位、尾码占n=23位。
8位阶码字段 e x p = e 7 e 0 exp=e_7 \cdots e_0 编码阶码 E E ,23位小数字段 f r a c = f 22 f 0 frac=f_{22} \cdots f_0 编码尾数M。

图2 单精度浮点数IEEE标准格式

根据阶码域exp的不同,可分为下列情况:

  • 非规格化(阶码全0)
    阶码 E = 1 ( 2 k 1 1 ) = 2 k 1 + 2 E=1- (2^{k-1}-1)=-2^{k-1}+2 ,尾数 M = f M=f ,用来表示0以及靠近0的数。
    最小非规格数尾码 M = 2 n M=2^{-n} V = 2 n 2 k 1 + 2 V=2^{-n-2^{k-1}+2}
    最大非规格数尾码 M = 1 2 n M=1-2^{-n} V = ( 1 2 n ) × 2 2 k 1 + 2 V=(1-2^{-n}) \times 2^{-2^{k-1}+2}

  • 规格化值(阶码非全0或非全1)
    阶码 E = e x p ( 2 k 1 1 ) E=exp-(2^{k-1}-1) ,尾数 M = 1 + f M=1+f ,其中尾数加1用于获得额外精度。
    最小规格化数阶码 E = 2 k 1 + 2 E=-2^{k-1}+2 、尾码 M = 1 M=1 ,值 V = 2 2 k 1 + 2 V=2^{-2^{k-1} + 2}
    最大规格化数阶码 E = 2 k 1 1 E=2^{k-1}-1 、尾码 M = 2 2 n M=2-2^{-n} ,值 V = ( 1 2 n 1 ) × 2 2 k 1 V=(1-2^{-n-1}) \times 2^{2^{k-1}}

  • 特殊值(阶码全1)
    尾数域全0时,无穷大;尾数域非0时,NaN(Not a Number)。

图3 8位浮点数非负值示例(k=4, n=3)

非规格化数分布在0附近,浮点数并非均匀分布,约靠近原点处约稠密。

整数 12345 12345 转为单精度浮点数,二进制数为【11 0000 0011 1001】,小数表示为 1.1000000111001 × 2 13 1.1 0000 0011 1001 \times 2^{13} ,因此存储为:

  • 符号域(1位),【0】;
  • 尾码域(23位)丢弃开头的1,并在后面补10个0,【100 0000 1110 0100 0000 0000】;
  • 阶码域(8位)为13加上偏置127,【1000 1100】;

猜你喜欢

转载自blog.csdn.net/sinat_34072381/article/details/82915003