计算机基础知识讲义全

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

习惯经验的强大惯性,源自于背景的长期稳定性。软件体系的快速变革,让我们忽视了硬件体系的长期稳定。这种稳定性使得很多习惯经验变成了不言自明的信条。大多数的软件设计方法的革新只不过是用旧石斧打造出来新石斧。在C中我们使用getc,putc来进行IO,在Java中无非是变成了

System.in.read(),System.out.print ()。为什么IO必定是这种形式呢?这是因为我们长期使用着同一种计算机。我们知道PC/Mac这样的计算机中CPU与IO设备进行通信,需要通过各种总线。下面这图演示了CPU与IO设备之间通信的基本过程.

以C语言为代表的传统的IO,实际上是单CPU上单任务工作模式的投影。在单台计算机上, 传统计算机体系结构决定了CPU处于控制者和决策者的地位。换而言之,我们历来习惯于以CPU的视角来考虑程序的IO逻辑.程序员是将自己假设为CPU. 程序员关心的IO设施只是一个黑盒.我们只需要往IO发送一个请求,然后等待请求回来进行运算,完全不关心这一来一回之间到底发生了什么过程.

但是当我们打开黑盒,观察CPU与IO的通信过程的时候, IO Monad就从幕后走向了台前。以总线的角度看,CPU和外设是等同的,都只是一个具有运算能力和输入输出端口的黑盒.总线正如Bind/>>=函数一样不关心这些黑盒子里如何运算的,它只关心从这个黑盒拿数据出来放入那个黑盒. 从整个计算机的体系结构看,传统的IO观念只不过是IO Monad的一个局部化形态。

IO Monad实则上在一些接近操作系统底层的软件中,经常扮演者数据总线这

种核心角色。比如说Unix/linux shell的管道命令就是彻头彻尾的IO Monad. cat,命令是return/Unit函数,|管道符就是bind/>>=函数。例如:cat sample.txt|grep "High"|wc –l .cat 将sample.txt的文件容包装成stdout,|管道符将stdout的容传给grep 命令查询所有单词位High的行,查询的结果又被转化为stdout,再通过|管道符传送给wc命令进行行数统计。微软最新的Shell取名为Monad,其言下之意恐怕无需赘述了.

不仅如此,IO Monad在结构化程序语言的最初演化的阶段也残留了一些踪迹.很多古老的Pascal程序,都保留了在程序首部书写Input Outpu参数的习惯. program fac_n(input,output);

var

n:integer;

function fac(n:integer):integer;

begin

if n=1 then fac:=1

else fac:=n*fac(n-1);

end;

这就是把程序的主体看成IO Monad上的一个计算函数。所有的Pascal函数可以通过操作系统的IO设施串联起来.当然随着程序语言往CPU中心化的演化,这些痕迹就逐渐消失了.

Monad仅仅是一个数学框架,并没有提供什么新的软件技术。在Monad 诞生之前,程序员们就已经在广泛的使用类似的软件设计方法。但是这些设计方法本身却无法回答我们一系列的追问:Exception,IO,Pipeline,为什么这些毫不相关

的领域中都会出现相同的数学结构?为什么在不同的领域呈现的Monad 特性完全不同,有的多有的少有的甚至完全消失?这些相同的结构的背后又预示着什么?以及,我们为什么要问这么多为什么?这些问题的答案对我们的编程实践又有什么意义?

(2)关于两个世界体系的对话

并行计算,是一群顽皮的孩童,充满着生机勃勃的活力,却又不失恶作剧式的顽皮。他们仿佛是一座活跃的“火山”。他们身上惊人的能量只有正确的引导下,才能完全的绽放出来而不致埋没;他们身上顽皮的天性只有在严格的教导中,才不会变成脱缰的野马而无法驾驭。正如儿童的教育首先需要深入他们的心世界,我们也必须深入并行计算的本质,去探究这些孩子心中的陌生而又神奇的世界。

在这群孩子们中间,并发是与我们最为的亲密也是最让我们头疼的一位。如何对付并发?目前存在两个截然对立的答案,Thread Model Vs Event Driven.对这两个模型,在编程实践的层面上我们都经过了严格的探讨,也有很多人通过各种途径去尝试调和其中的分歧。但是Which is a bad idea?是一个至今争论不休的问题。我认为这不是仅靠分析他们各自优劣就能解决的问题,而是必须解释清楚为什么会产生这两种截然不同的方案。知其然,必先知其所以然。只有回到问题的源头,才能以更宽广的视野去选择道路。

在我们介绍IO Monad的部分时,曾经略带提过计算机体系结构决定了程序员以CPU为思考中心的习惯。这个计算机模型,就是统治我们现在大多数计算机

部构造的诺依曼模型。

在计算机中存在两种不同的流,一种称为控制流(Control Flow),另外一种则是数据流(Data Flow)。计算机要进行工作必须要通过其中一种进行驱动。•诺依曼机的核心工作方式是控制流(指令流)驱动。即按照指令的执行序列,依次读取指令,然后根据指令所含的控制信息,调用数据进行处理。•诺依曼机为了控制指令序列的执行顺序,设置一个程序(指令) 计数器PC(Program Counter),让它存放当前指令所在的存储单元的地址。如果程序现在是顺序执行的,每取出一条指令后PC容加l,指示下一条指令该从何处取得。如果程序将转移到某处,就将转移的目标地址送入PC,以便按新地址读取后继指令。

Program Counter是一个递增的自然数。我们知道,自然数集具有严格的顺序性,1<2<3,这种特性的集合在数学上被称为偏序集。如果我们在两个偏序集中找到一个函数那么我们称f为保序的连续映射.

在诺依曼机中,正是通过时钟发生器与PC,PC与存地址之间的连续映射把CPU 时间的顺序性映射到了代码的顺序性。比如X86 CPU大致就可以分为下面几个时钟周期.(FC为取指令周期,SC为源操作数周期,DC为目的操作数周期,EC执行周期,IC中断相应周期,DMA,DMA传送周期)

相关文档
最新文档