计算机组成原理 - 理解内存

计算机最重要的是 CPU,除此之外,第二重要的就是内存,内存属于计算机五大组成部分中的存储器,我们的指令和数据,都要先加载到内存,才会被 CPU 拿去执行。

之前有篇提到过,程序并不能直接访问物理内存,而是通过虚拟内存地址转换到物理内存地址,从而加载数据,那么虚拟地址究竟如何转换成物理内存地址的呢?

Read More

计算机组成原理 - 高速缓存

来看 3 行代码,比较一下两个循环运行所花的时间。

1
2
3
4
5
6
7
int[] arr = new int[64 * 1024 * 1024];

// 循环1
for (int i = 0; i < arr.length; i++) arr[i] *= 3;

// 循环2
for (int i = 0; i < arr.length; i += 16) arr[i] *= 3

按道理来说,循环1 花费的时间应该是循环2 的 16 倍左右。但实际上,循环1 在我的电脑上运行需要 50 毫秒,循环2 只需要 46 毫秒。相差在 15% 之内,1 倍都没有。

这就是 CPU Cache (高速缓存)带来的效果。

程序执行时,CPU 将对应的数据从内存中读取出来,加载到 CPU Cache 里。这里注意,CPU 是一小块一小块来读取数据的,而不是按照单个数组元素来读取数据的。

这一小块一小块的数据,在 CPU Cache 里面,我们把它叫作 Cache Line(缓存块)。

日常用的 Intel 服务器或者 PC 中,Cache Line 的大小通常是 64 字节。

上面的循环2 里面,每隔 16 个整型数计算一次,16 个整型数正好是 64 个字节。所以,循环1 和循环2,都需要把同样数量的 Cache Line 数据从内存中读取到 CPU Cache 中,导致两个程序花费的时间就差别不大了。

Read More

计算机组成原理 - CPU 的指令周期和数据通路建设

我们知道,在 冯·诺依曼 的提出的计算机模型中,计算机是由五大部分组成:运算器、控制器、存储器、输入设备、输出设备。

其中,运算器和控制器一般会放在一起,即我们的 CPU (中央处理器),负责指令读取和计算。

指令一般分为三类,R 型:进行算术操作、逻辑操作;I 型:进行数据传输、条件分支;J 型:地址跳转。

有了这些基础,那么完整的 CPU 是怎么运转起来的呢。

Read More

计算机组成原理 - 浮点数和定点数

如果你有 python 或者 node 的命令行终端,或者浏览器里面的 Console,你可以做个测试,输入 0.3 + 0.6 看下值究竟是多少。

1
2
3
4
Welcome to Node.js v12.16.1.
Type ".help" for more information.
> 0.3+0.6
0.8999999999999999

Read More

计算机组成原理 - 二进制编码,电路

所有数据,字符串,整数等一切事物在计算机里,都是通过 0 和 1 来组成,也就是用二进制表示。二进制的特点就是「逢二进一」。

同时为了应对负数,采用了补码表示法,即第一位既作为符号位,同时也参与运算。比如 4 位二进制数,从 1000 到 0111,表示的范围在 -8 到 7 之间的 16 个数,不会浪费任何一个位。

有了补码表示负数,整数相加也变得很容易,不需要做任何特殊处理,只是把它当成普通的二进制相加,就能得到正确的结果。

Read More

计算机组成原理 - 程序的链接,装载和执行

本文打算从 ELF文件格式静态链接,程序装载,动态链接三个方面来分析一下,程序如何链接,装载和执行的。

Read More