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

来看 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

计算机组成原理 - 指令

CPU 能处理的只有指令,我们写的程序归根结底就是指令,高级语言只有翻译成机器码,即计算机能够识别的指令,才能够被执行。

Read More