数据结构与程序架构(三)

在上篇文章中,我们看到了硬件工程师在设计程序(即逻辑电路)时是很直观的,直观就意味着容易理解和检错;同时,我们也能看到这种方法的强大,通过将基本处理单元连接成特定的拓扑结构,就可以实现某种特定功能的计算;而且,这也体现了这种方法的灵活性,当面对新需求时,我们只要设计出能处理这一新需求的拓扑结构即可;另外,值得一提的是,这种方法是高度模块化的,任何一个处理单元都可以被另一个功能相同(但经过优化)的单元替换,且即使(新单元的)接口有变化也没有关系,我们只需要增加相应的其它处理单元即可。

以上这些优势使得硬件程序普遍的比软件的质量高而且稳定,如果我们能在软件的架构设计中也引入这样的方法,可以想像它能给我们带来多大的好处!然而,这并不是一个简单的任务,困难主要来自于硬件程序和软件程序的执行机制不同。

我们知道,在物理电路中,信号可以通过并联电路同时传递给不同的处理单元,然后在这些单元中进行并行的计算,硬件设计师只需要处理好不同处理单元间的信号同步问题就可以了,正是这种高并发的物理特性,以及信号同步的可控性,保证了即使逻辑电路的层次非常多,拓扑结构非常的复杂,程序也能够高效且稳定地运行。

然而对于软件程序来说,它具有典型的串行执行的特征,即使现在我们的PC和智能设备已进入了多核时代,但与大型软件复杂的模块结构相比,其并发能力也是非常可怜的,而且这种并发控制目前都是由操作系统管理的,而操作系统对于一个程序可并发执行的线程数量是有限制的,而且操作系统的整体性能也会受到一个程序所创建的线程数量的影响,所以当一个软件的模块结构超出了这一限制,我们就不能简单的通过增加线程来模拟硬件程序的执行机制了。那么,此时我们要怎么办呢?

第一感的想法,是逐个的执行处理单元,然后把它产生的输出传递到下一个处理单元,如果我们的程序模块具有链式的结构,这种处理方法是可行的,但是如果是更加复杂的结构呢?比如一个处理单元需要多个其它处理单元的输出(即多对一结构),或者一个处理单元会输出到多个其它处理单元(即一对多结构),甚至一个处理单元需要它自身或其它处理单元上一次执行的结果(即反馈回路),深入思考一下这些情况,不难发现要决定下一个处理单元将异常的繁琐,而这也预示着这个调度程序(即程序的框架)将非常的复杂,而且容易出错,很可能使得我们得不偿失。所以,我们需要想想别的方法。

既然正向决定下一个处理单元不行,那逆向行不行呢?即,我们先确定一个最终输出单元,然后看它的输入缓冲区中是否有数据,如果没有,就给它的所有输入单元发出一个信号(这个信号可以是一个真实的数据信号,也可以是一个假想的信号,即触发某些操作,下文会有所体现),要求他们提供数据,然后它的所有输入单元此时就变成了当前的输出单元,然后逐个的检查它们各自的输入缓冲区,并重复同样的过程,直到某个初始输入单元或反馈单元。

不难想象,利用上面的过程,我们可以构建出一棵树,来反映信号传播的路径。而一旦我们得到了这棵树,那么从树叶(即初始输入单元或反馈单元)到树根逐层去计算各自的输出就是非常简单的事情了(还是一个深度优先的遍历算法)。如果你理解了这个算法,是不是觉得一切问题都迎刃而解了呢?而这个算法就叫“以需求驱动”的设计思想。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值