0和1

littletim
2018.07.29 11:08 字数 3307 阅读 81评论 0

0 和1 可能是在程序员的心里最美的两个数字了,今天准备聊聊在计算机内部信息编码和存储,计算机中几个重要的存储系统以及纠错和数据压缩技术。

数据存储:

在《深入理解计算机系统》(CSAPP)中有一句话,信息=位+上下文。这句话可谓是精辟。在计算机中,信息以二进制的方式存储在物理存储器上,物理存储器可以是磁盘,固态硬盘,主存,寄存器,它们的读写速度和造价以及内部原理差别很大,但是信息在这些物理存储器上的形式都是二进制,这些存储器的每一个基本存储单元只有两个状态表示0或者1,这称为一个位(bit),比如在磁盘中每个磁质单元的磁性表示位的信息。通常我们用字节给位计数,1个字节=8个位。

如有侵权,请联系删除

位在计算机中是如何被操作的呢?我们可以将1看成true, 0 看成false。下面介绍一下布尔运算。布尔(1815–1864)是一位逻辑学的先驱,三个基本的布尔运算是AND,OR,XOR以及NOT. AND表示和,只有当两个输入为1的时候才输出1,否则输出0。OR 表示或,当两个输入都为0,则输出0,否则输出1。XOR 表示异或,只有两个输入为1另一个输入为0的时候输出1,否则输出0。NOT表示反,输入0则输出1,输入1则输出0。这些布尔运算可以在物理层面用电路实现,称之为门电路,可以想象一下场景,两个输入以电流的形式输入,经过一个物理门电路后,输出一个电流脉冲,这个是计算机处理单元最简单的模型。这些简单的门电路经过一系列的串并联后实现复杂的功能。今天的CPU功能和设计很复杂,但是基本原理离不开布尔运算和逻辑电路。


如有侵权,请联系删除

那么怎么以二进制存储信息呢?比如一个10进制的数1024,在计算机中的是怎样被存储的呢?可以设想一种简单的情况,我们规定将1024以它的二进制形式存储在计算机中。那么利用高中学的知识我们可以很容易得到,1024的二进制是10000000000(2),即2的十次方(在计算机中表示存储的大小比如B,KB,GB,TB,它们的大小都是上一个的1024倍,1KB=1024B,1GB=1024KB,1TB=1024GB)。但是实际在计算机中,信息存储并没有这么简单,有众多复杂的编码算法。介绍一种较为简单和常见的编码方式:补码。我们在存储系统中开辟一块固定大小的空间比如16个BIT(当今32位机还是16位机看的就是在该机器中整数存储使用多长的字节,若使用2个字节则是16位机),存储整数。你可能想到,把整数转化为二进制直接存储不就行了,可是负整数怎么办?人类发明了一种补码系统,即这32个位的存储快,我们把第一个位表示这个被存储的数是正的还是负的,正的话第一位就置为0,负的话第一位就置为1,然后剩下的位就用来存储它们绝对值的二进制表示,比如1024就会被存储为0001000000000000。那么计算机如何执行你给的一个命令比如:“把1024加上1024结果返回给我”? 你可能想到用上面介绍的逻辑电路,我把两块存储内存存储1024,然后用CPU给它算一下就行了。事实上计算机确实就是这样干的。虽然现在有很多被吹得很火的概念比如:人工智能,智能计算,计算机好像是一个拥有智慧的机器,神乎其神,但是在计算机内部它能做的事情很少,这个也解释了为什么计算机运算能力这么强大,因为它简单粗暴!但是聪明的你可能会发现,这种编码方式存在缺陷,比如你要存储一个特别大的数,或者你想计算100000*100000,这个就没有办法做到了,甚至如果你仔细想一下的话,如果按照我们的方法,我们计算一下5096+5097(0100000000000000(2)+0100000000000001(2))的话,你会得到1000000000000001(2),按照我们之前的规定这是一个负数!事实上,这是很多菜鸟程序员经常犯的错误,他们经常吐槽,“我X,程序运行出来怎么会出现这样的结果?”,据说有一次重大的航天事故就是因为设计控制系统的程序员犯了类似的错误,这种错误应当由编写程序的人负责!还有一种值得注意的是舍入误差,举个简单的模型,如果我们用一个小数的十进制表示的每一个位存储这个小数的话,当我们存储1/3的时候就会出现舍入误差,我们不可能用一个无限大的内存存0.3333333333333333333333333333333333333333333...吧。比如现在人们可以用计算机快速算出有几万甚至几百万个未知数的线性方程的解,但是如果你没有采用数值优化算法的话,因为舍入误差,你最后可能得到的是一个完全错误的结果。你看虽然计算机的算力强大,还是有很难做的事情。

信息在计算机的存储向我们展示了抽象和简洁带来的巨大力量。现如今,计算机系统渗入了人类生产生活的方方面面,比如工业控制系统,互联网,医疗设备,家用计算机和家用电器,都能看到计算机的身影。而作为计算机的一个重要的组成:存储单元,它们都采用了同样的存储形式,真的让人惊奇,正如道家所说“道生一,一生二,二生三,三生万物”,不管是视频,文本,音频,CPU指令,都是以二进制的形式存储,0和1 构建起了信息世界。

几个重要的存储系统:

计算机中的存储系统都是朝着更快,更大,更便宜的方向发展的。计算机有内存,磁盘,寄存器等。如果你在网上搜索一下的话,当然你不会发现有人直接卖寄存器,寄存器被设计在CPU内,你会发现同样是存储系统,一块16G的三星内存条要7,8百软妹币,但是一块1TB的磁盘可能只要3,400。原来在存储的世界,也有“出身下贱”的现象啊。为什么差距这么大呢?最重要的原因是制造读写速度越快的存储器,成本越高。而往往读取速度越快的存储器,它的存储量越难做得更大。计算机系统的设计也是充分利用这点,系统的设计者把读取频率大的信息放在速度快的存储器里面,这就像你会把经常看的书放在手边一样。设想一下,即使现在的CPU运算速度很快,一秒上亿次,但是存储设备不能快速的把需要运算的数据给CPU,CPU高喊这“我算完了,下面的任务呢?,然后存储器慢悠悠地花了好几秒才把数据传给CPU,CPU运算得再快也没用,这样真是个灾难!计算机系统设计者想到一个好的办法,把不太需要的数据放入硬盘,当计算机启动,就把需要的信息从硬盘放到内存,内存的读取速度可快多了,比如当你打开电脑,你的word软件和你的视频都放在硬盘内,你点击打开word软件,word代码文件就会被提取到内存,但是你的视频还放在硬盘内。值得注意的是内存是易失性存储,一当断电里面的东西都没了,这就是为什么当你的电路突然断电后,你再次打开电路,会难受的发现没有保存的文件都不见了,因为当电脑断电的时候,你的未保存文件还放在内存,并没有写入硬盘。当文件被放入内存后,CPU的设计者觉得内存的速度还是太慢,简直拖CPU的后腿,他们在CPU内设计了更快,当然更贵,而且存储量更小的存储器叫:寄存器。寄存器用来存储CPU运算单元“急切”需要的数据。当然现代的计算机系统的设计比上述所说的模型复杂多了,比如说会有很多级的缓存区,但是设计的基本思路不变。

数据压缩和纠错技术:

数据压缩技术比较常见,比如你可能经常需要解压和压缩文件,数据压缩分为:有损压缩和无损压缩,顾名思义,无损压缩强调经过压缩和解压缩得到的信息不变,而有损压缩会造成信息的部分丢失。有很多性能优异的数据压缩算法,可以去网上搜索。我想简单介绍一下纠错技术。实际上,数据在存储器的存储并不是十分安全的,比如在天空中,收到电磁辐射的影响,硬盘甚至电路的0会被改变为1,在信息传输过程中也会遇到上述问题,比如你发给Alice的情书被划分为很多数据包通过网络发送给Alice,其中有几个数据包被坏人篡改了,如何保证Alice依然能准确无误地收到你的信息呢?


如有侵权,请联系删除。注:在太空的ThinkPad

人们发明了众多编码技术,不仅能够探测到信息是否被修改,甚至可以用一定的数据冗余保证在一定的错误率下,可以通过纠错得到正确信息。下面介绍一种简单的error-correcting codes。

首先介绍一个概念,汉明距离(Hamming distance), R.W.Hamming是研究纠错编码的先驱。汉明距离值的是两个位模式不同位的个数,比如下图的A,B之间的汉明距离就是4。B,C之间的汉明距离为3。值得注意的是,下图所有的编码模式之间的汉明距离都大于等于3,这是一个很好的性质。如果下图中的位模式在传输的过程中,有一个位(bit)被改变,我们可以立即发现。

如有侵权,请联系删除

利用这个性质我们可以纠错。比如说我们收到一个位模式:010100,经过查表发现这是一个非法的位模式,经过计算,发现这个位模式距离上图代表D的位模式最近,那么我们有很大的把握认为发送的位模式代表的是D。


如有侵权,请联系删除  

当然上面介绍的是较简单的纠错编码,推荐阅读一下Berlekamp-Welch算法,该算法广泛应用于通信,有专门的硬件芯片实现该算法。值得注意的是,上述纠错编码系统均存在数据冗余,正所谓天下没有免费的午餐,为了能够纠错,必须做出一定的牺牲,比如上面的利用汉明距离的纠错编码会导致传输空间的一定浪费,在6个位下只能传输8个字母。

粤ICP备13004853号-7