我对计算机的个人理解:概述

定义

计算机就是人类能告诉它想要做什么,然后它做好后告诉我们结果的机器;

数据

假设我们处于一个幻想出来的平行空间里面,由我们来设计出这种叫计算机的东西。

首先我得让计算机能明白我们这个世界。所以第一件事情就要给这个世界所有事物命名。

我们需要制定一种规则,能用最简单的方法表示世界万物。这个当然必须求助于数学,而数学中最简洁的表示方法就是布尔数学。只有0跟1。这个跟计算机的运行机制太贴合了。因为集成电路有高电平和低电平两种状态。

那么我们可以想办法开始用0跟1给这个世界命名了(二级制)。首先想到的是给0-9、A-Z这些数字和字母、标点符号命名,假设能做到,那么至少用来写文章是没有问题的了。

让我们来看布尔表示方法,一个布尔数字只能表示0跟1,两个不同的东西,太少了,如果是我们每次用两位数字来表示呢?那就有00、01、10、11四种状态,可以表示四种东西了。由此推论,还可以用3位数、4位数等等……它能表示的种类数量,就是2的N次方之多。2的7次方是128,2的8次方是256,理论上128已经足够实现我们上面的要求了,(想想我们键盘也就100来个符号),但是加上一些特殊点的符号,应该会超狗这个数了,那么还是用256的空间来表示吧。

于是,这个世界就有人站出来这么干了,他们每次8位的布尔值来给这个世界编码,规定好了从0到255个编码,各种是代表了什么含义,比如字母“a”的标号是97,“b”是98……等等,他们把这套编码规则叫做ASCII编码。

而人们把每8位(bit)布尔值,取了个概念就叫做一个 字节(Byte)

所以编号97本来是没有含义的,但是自从有人向全世界宣布它代表了“a”,它从此就有了含义。此时正如上面所说的,用这些编码写点文章是够了。可是注意,前提是英文文章。英语有26个字母就搞定了,可中文呢?好像没法拆解成几个字母的表示哦,所以天然就需要很多编码来表示了。于是后面的人们,就发明了各种的编码规则来表示,有GBK啦,UTF8啦,unicode啦。各国的编码都可能不一样,所以后面的unicode是来了个大统一,搞出了一套国际通用的编码,从8位扩展到16位;16位的编码空间哦,可以表示65536(UCS-2),甚至后面还有用32位表示的(UCS-4),也就是可以表示4,294,967,296种东西,足够表达全世界所有的语言文字了。

读取数据和指令

很好,现在全世界的东西都可以给它命名了。要是计算机能够理解得了,它就能懂的我们要它干什么了对不?

那么该如何设计这个能读取这些数据的机器呢?让我们回想一下对世界第一台计算机的些许印象,什么占了好几个大房间、科学家得用纸带打孔输入,等等……

对,那时候科学教就用打孔的纸带来输入信息的,想象人们在纸带上打孔,有孔的代表1,没孔的位置代表0,往机器里一插。那台机器就咔嚓咔嚓把纸带吃下去了,于是就一位一位的识别这些信息。科学家告诉它要做什么,比如……嗯,计算1+1等于多少?它就默默的执行起来,然后计算出结果,再显示出结果(一排灯泡亮了),于是科学家很开心地把结果抄下来。over!

等等!这里有点问题,我们前面只对世界进行了编码,这些东西只能叫做“数据”,或者“信息”,我们要计算机帮我们做事情,得告诉它要怎么做。比如“显示123456到显示器上”,只有123456跟“显示器”是不够的,还有有个“显示”的动作。

所以我们得干多点活,把这些动作也规定一下。这里我们把它叫做“指令”。是否需要找另外的表示方法来表示指令呢?我们得明白,创造一个新事物的原则一定要简洁。所以,我们无需找其他方法了,我们可以继续用0跟1来表示操作。只要规定那些编码是代表什么样的操作即可。比如我们可以规定0001是加法,0002是减法。在强制规定,每次我们都是前面一个“操作”,后面一个“数据”,不就行了?计算机每次都一段一段的读取,就知道我们想干什么了。这里的每一段,我们都叫做一行“指令”。

比如下面这样一串0和1:

10100001 0000011 00000000

就表示下面的意思,将三号单元的数据取出放到AX寄存器。MOV是操作,后面是要操作的对象。

MOV AX, [3]

这个其实是汇编语言的指令来的,它的含义以后再说,先不理会。另外,它的前提是在某一种特定的CPU上才能识别。

实际上,这世界有很多上面说的“计算机”,它们对同样的指令,定义的含义都不相同。所以呢,上面的指令必须要在指定的CPU上运行才行,否则人家肯定会搞错。幸好,这世界目前最主要的CPU厂商就Intel和AMD两家。

内存和显存

接下来打算讲一下CPU怎么处理数据。不过光讲CPU不能让我们理解它能干什么。要知道,我们平时印象中的计算机,就是一台台PC主机或者笔记本,这两者共同之处就是有键盘、显示器、里面还有能保存数据的硬盘等等。如果CPU那么重要,那么它如何让这些硬件做到平时那些神奇的事情的?

这里的“神奇的事情”,可以很简单,比如在显示器显示一行字,我认为也非常了不起。

让我简单解释一下背后的原理。显示器要显示东西,得有显卡这个硬件设备支持。显卡里面最重要的是显存。显存么,其实就跟内存一样,可以看做有很多格子,每个格子可以放进0或者1;每个格子都有一个编号,可以从0到1000,甚至到40亿等。

而设计这些硬件的人,就规定好,如果往显卡里面写入的数据,就直接显示到显示器上。而要写入什么样的数据,这要从显示器的设计开始说起。显示器的屏幕是由一个个像素组成的,每个像素可以显示红蓝绿三种原色,每种 颜色能调整亮度,分别从0到255个级别。这三种原色的不同轻重程度一组合起来,就能显示几乎所有我们肉眼能看到的颜色了。

这样的规则就叫RGB模式(red、green、blue),0到255级的灰阶表示,其实就是8位二级制表示;再加上一个Alpha通道,用于叠加时计算透明度的,加起来就是8*4=32位的表示,也就是4个字节。

所以4个字节的信息量就能表示一个像素的千变万化了。而一个屏幕有多少像素呢,比如1024x768大小的屏幕,就是1024x768x32/8=3145728个字节。也就是3.14M。这意味着如果我们的显存至少需要3.14M的空间大小,才能一口气保存整个屏幕的一帧画面了。如果需要更加流畅的话,那最好能同时保存多帧图像。否则一些高速视频看起来会卡,有可能跟显存大小有关系。

由此我们明白了,往显示器上显示东西,就是往显存里面填格子。格子的数据都对应到像素上去了,所以填了什么,就显示什么。这种模式非常简单高效。

而其他硬件也是基本按照这种思路来设计的了。比如网卡,收发数据都是这种“读写格子”的方式。

那么谁来做这个读写格子的操作?CPU。

CPU又怎么知道有这些硬件设备了?要知道各种硬件设备都要接到主板上,那些固定的还好,有些像USB设备却有可能随时被拔插。让CPU每次都去找有什么设备存在?这太复杂了,关键是CPU找到了也未必怎么怎么去用这些硬件。

还好科学家的思想就是把一件复杂的事情变得很简单。他们让CPU不去跟这么多硬件打交道,而是只跟一样东西打交道就行了,这样东西就是内存。

内存也是一堆格子,同样每个格子都有编号,俗称内存地址。1K内存就是1024个格子,1M内存就是1024*1024个格子,以此类推。不过注意每个格子包含了8位二进制数据,而不是1位。

这就是像一个旅馆,有各种房间,而每个接入的硬件呢,就当做客人,给它安排好从哪个门牌号到哪个门牌号。以后,CPU需要往显卡里写入数据,它只需要找到显卡在内存中的地址,然后往这个地址写入数据就可以了。

话说回来,这事情也没有那么简单,毕竟每个硬件的操作方式都是不一样的。不过科学家们有的是办法,他们在每个硬件上加了一个叫BOIS的东西,这东西就是做操作这些硬件“读写格子“的。

所以上面写入显存实际上是传给显卡的BOIS,由BOIS写入到显存中合适的位置。

而CPU本身是不懂怎么去干这些事情的。这些事情是由人们编程来干的。每个硬件要能被使用,它的厂商就得提供一套对应的程序,这些程序就叫驱动程序。相信每个用电脑的人免不了都有安装驱动一类的经验。而管理驱动、调用驱动,也不是由CPU直接做的事情了,它不懂。因为这太复杂了,同样得有一套程序来自动处理这些事情,这个程序叫做操作系统。

CPU

用纸带来读取数据操作计算机的方式实在太低效了,好在科技不断发展,由集成电路制造的微处理器出现了,也就是现在说的CPU。

一个CPU要干什么?通过上面对内存的介绍,我们知道它其实要干的,就是“读写格子”。

我们可以设想我们每次都能读取一位二级制数据,然后再处理。这样子就很难区分指令出来了,因为一条指令怎么也得3、4位才能表示,一位毕竟太少。那好,我们就让CPU一次能读取多位,需要多少呢?一次能搞定一条指令i最好了。

CPU要完成一条指令,至少需要知道它要干什么,要操作的数据是什么,还有一个很关键的,它要做的事情是读还是写?

所以,一次读取的数据还可以更多一点,一次读入一条指令,几位数代表操作,几位数代表数据,一位数代表读或者写。

CPU总线 (图片来源于网络)

如果一种线路一次能读个16位的数据,那就是16位CPU,能读32位、64位呢,就是现在常见的32位或64位CPU了。

一旦通电之后,CPU便开始运作。它要做的事情就三件事:读入数据,处理掉数据,通常还会把数据写回去。整个过程像流水线一样不停重复执行,断电之前从不停止。

为了做到这些,CPU包含了多个部件来完成:

  1. 首先,要读取每一条指令,需要知道从内存中哪里读取,这点由指令指示器获取;
  2. 然后由取指器取出指令;
  3. 其次,解码器会将指令翻译成硬件能理解的语言,有时候一条指令需要分解成好几个步骤才行;
  4. 真正负责加减等数学运算和逻辑运算的是里面的ALU,全称算术逻辑单元;
  5. 这个过程可能需要临时存储一些数据才能完成,所以又包含了一些寄存器;
  6. 而负责控制以上整个流程的,就是里面的控制器元件了;

无论我们平时看到计算机在做什么,播放视频、玩游戏、甚至哪怕打出一个字符,都是上述的过程,只是这个过程重复得极快极快。

有多快呢?看另外一个部件:时钟发生器,它用来调节这个做事的频率,也可以看成干活的速度。这个频率的参数就是我们经常听到的2.4GHZ,2.6GHZ等,一般同等条件下2.6GHZ确实比2.4GHZ处理速度快(不过考虑到其他硬件条件往往就不一定了)。2.4GHZ就是意味着一秒钟可以做24亿次的计算了。所以哪怕我们明知计算机在做的事情很复杂,我们肉眼也察觉不到这过程。

不过这么快也会带来一些麻烦,比如老是要跟内存打交道,内存的速度可是慢得多了,比如1333MHZ的频率,差几十倍。读写内存的时候CPU不就得慢慢等了?这好比拿着茶杯去水池舀水一般,干着急。

所以人们发明缓存这种东西。缓存在计算机科学里是常见的概念。这里的缓存是讲一种硬件,相当于一个水桶,先去水池里一次舀一大桶水出来,然后才让给茶杯慢慢舀。因为缓存的速度极快,可以跟得上CPU的要求,只可惜它的造价太昂贵了,不能随便来个几G容量,通常都是2M、8M这样子,考虑到这点,就加入了一级缓存、二级缓存、甚至三级缓存的硬件了。二级缓存显然就比不上一级缓存快,但人家体积大啊,可以当作个蓄水池用,拿水桶的不用老跑去水池舀了。这样子接力,CPU工作起来的性能,就大大提高了咯。

实际上,这种思路在计算机很多地方都会体现。比如,内存也可以看做更大一层的“四级缓存”,再往下还有容量更慢、体积更大、造价却更便宜的硬盘,甚至再往下,还有网络这一层,同样可以包含在这个金字塔形状的模型里。

金字塔结构 (图片来源于网络)

(未完待续)