共享的边界如何覆盖独享

今天读了一位朋友写的一篇关于linux调度域的文章,感到甚是有用,读了以后发了一番感慨如下:

SMT共享了ALU,然而却独享了寄存器;MultiCore共享了L2 Cache,然而却是独享L1 Cache的;SMP共享了内存,然而每一个处理器却是独享Cache的;NUMA的所有节点共享了存储阵列,然而每个节点却是半独享内存的;多台计算机共享了整个网络,然而却独享着自己的内存,外设...整个网络独享着数据,然而却共享了世界!这是一幅美丽的画卷,如此和谐又如此对称,这个画卷反复重复着共享与独享之间的合作而不是争夺,某些意义上,独享是为了精确分工,而共享是为了不同工作者之间高效地合作。

资源的分配方式总是在各个层面影响工作的效率,资源的分配总的看来有两种方式,一种是将一个资源独占式的分配给工作者,这样该资源只能由它的属主工作者利用,别的工作者完全访问,另外一种就是共享式分配,指的是资源可以由所有的工作者利用。如果确定性的,一个工作者使用的资源绝对不会被别的工作者使用到,那么这个资源就可以独占式的分配给该工作者,然而如果一个资源需要很多的工作者来访问,那么就应该以共享的方式分配。自从分工开始以来,人类就面临资源分配的问题,随着分工的细化,社会化生产成了一个时髦的词,在工业界形成了流水线这样的工程解决方案。分工就是为了更好的协作,为了更有效的产出,因此不可避免的要面临工作者之间的通信问题,凡是涉及到这部分问题的资源就要以共享的方式进行分配,其实完全可以消除共享,用专门的通信规范进行工作者之间的通信,然而那样的话会带来很大的开销,而共享资源的方式无疑是最高效的,因为对于工作者来说,用自己的东西肯定是最高效的,共享的东西对于每个工作者来讲都是自己资源。

对于分工来讲,无非两种方式,一种就是消除时间上的浪费,另一种就是消除空间的浪费,后一种比较容易实现,无非一个屋子里多安排几个工人罢了,我们对于空间的操控力总是强于对时间的操控力,对于消除时间的浪费就不是那么容易了,我们必须将一个按照时间序列化的工作分解成好几个可以按照空间展开的子工作,事实上我们人类生活在时间轴上,一开始就是在时间轴上序列化做事的,因此将一个工作分解成n个子工作很有难度,虽然有难度,但是难度还不至于大到不可想象,在数学上有统筹学,在工程上有流水线,这些都是这种思想的体现,这些方案中,最重要的就是分解的子工作没有太多的共享资源,如果有的话就会产生共享资源的同步互斥问题,但是如果没有的话,那么这种分解就绝妙到了极点,完全可以消除资源共享。大千世界是很复杂的,不是什么设计都是绝妙的,按照道理来讲,不同的任务同时展开不应该用什么共享的资源,毕竟它们是不同的任务嘛,但是世界的事物不是孤立,世界因联通而精彩,因此共享资源的问题是不可避免的,不仅仅同一个任务的分解还是不同任务的并行。对共享资源处理的难度来自于我们对时间操作的难度,我们可以征服最高的山峰,可以征服太阳系甚至可以征服男人的下颚,可是我们却征服不了时间,时间的流逝速度和方向我们只有眼睁睁看着的份儿,因此对于分解的子任务,我们不能主动引导工作流何时使用共享资源,也无力扭转不同的子任务对共享资源的依赖关系,唯一能做的就是当冲突发生的时候,要么等待,要么丢弃已有的成果尽自己最大的努力来使得一切看起来安然。

这世上本来没有也没有必要有共享资源,参与者多了也就有了共享资源,因为联通使世界精彩。难道仅仅是联通的因素吗?其实还有一个因素就是为了高效,就是前面我说的,让大家都使用的资源真的归大家所有,任何工作者使用的时候就好比用自己的东西一样方便,这样可以节省很大的一笔资源重复建设的开销,为此付出的同步互斥问题值得。

好了,最后我们来用一种更加独特的眼光看一下资源的共享。前面说将单一的任务分解成不同的子任务之间或者不同的任务之间根本不需要共享资源,也就是说独享为主,共享为次,但是如果将一件工作分配给不同的工作者来做,并且不是像前面那样按照时间序列纵向分解而是横向分解,然后将少的多得任务分配给不同的工作者,这种模式中共享却比独享来的必然,所有的子任务都是一模一样地重复相同的事情,因此所有的资源都是共享的,但是这种分解有什么意义?其实按照上面的叙述没有什么意义,因为上面强调的是一个大任务的分解方式,本质上的说法应该是增加人手做相同的工作,显著的意义就是提高吞吐量,这个不用多说了吧。因此要么按照纵向的方式将流水线横向展开,然后并行化各个流水环节,要么增加人手,提高吞吐量,前者如果分解的好的话不必太在意资源共享问题,而后者则必须考虑资源共享问题。第一段中列出的计算机的架构的例子说明了计算机系统是一个复杂的系统,在资源分配上兼用了横向展开和纵向展开两类。因此虽然硬件提供了如此好的机制,操作系统内核必须提供策略来最大化的利用这种优势,最起码不要将这种复杂的机制变成牵绊,对于linux内核,负载均衡就是干这个事情的,为了负载均衡内核提供了调度域的概念,按照负载均衡的意义和代价将整个系统分为了多个调度域级别,其中最高级别的调度域中的负载均衡的代价最大,最低级调度域的负载均衡的代价最小,内核每各一段时间对各个调度域进行一次负载均衡,负载均衡代价越大的调度域其均衡间隔越大,因为内核为了尽量少付出昂贵的代价。内核的调度域的概念在软件层面上再现了第一段的美丽画卷的前半部分,也即是到NUMA的部分,操作系统内核的设计直接影响了上层软件的性能是否按照硬件的本意来体现。

你可能感兴趣的:(工作,cache,网络,负载均衡,任务,linux内核)