一般情况下,在SMP环境中,每个调度器都会绑定到一个CPU核心,为了保证调度器可以充分的利用CPU资源,那么就必要确保每个调度器任务队列的长度大致相同,Erlang通过任务迁移算法来完成这个功能。Characterizing
the Scalability of Erlang VM on Many-core Processors这篇文章中对这个算法进行了详细的说明,不过,就我自己感觉来说,边看代码,边看上述论文里的描述,可能更容易理解。这篇算是一个总结文档。
Erlang中每隔固定时间(R15B中这个值是2000*2000)会做一次任务检查,查看各个任务队列上的任务是否分布均衡。主要要做下面几个工作:
1) 确定活跃调度器数量;
2) 确定每个调度器的负载,根据每个队列当前的负载确定调度器之间的迁移阈值,高于这个阈值的队列需要迁出任务,低于的需要迁入任务;
3) 根据2)的结果,确定每个队列的迁移路线;
4) 在调度到一个需要迁入任务的队列时,从目标迁出队列迁移一个任务,直到达到迁移阈值。
在继续说明之前,需要了解到,在虚拟机实现上,上面提到的固定时间(2000*2000)又被切分成两个区间(每个区间1000*2000个reduction)。第一个区间时间到的时候,只做一件事,就是检查每个调度器任务队列的状态,如果队列处理等待状态,就会对该队列设置一个标记,否则清除该标记。第二个区间时间到时,才会完整的执行上述4个步骤。
活跃调度器数量
确定任务检查完成以后,活跃(active)调度器的数量。
任务检查涉及到的调度器运行时状态有2种:active,inactive(这两种状态的调度器统称online调度器;offline调度器处于suspend状态)。调度器处理active状态说明调度器的任务队列里任务充足,调度器一直在工作;处理inactive说明调度器没有工作,处理等待状态,如果其它调度器任务繁重,可以唤醒inactive的调度器。活跃调度器的数量Nactive主要由下面几个方面确定:
1) 在整个检查区间内从未进入等待状态的调度器数量Nfull_shed;
2) 在第二个区间内没有进入等待状态的调度器数量Nhalf_shed;
3) 当前在线调度器数量Nonline;
4) 当前活跃调度器数量Nactive_current;
5) 上次任务检查时确定的活跃调度器数量Nactive_begin;
6) 上次任务检查引起调度器数量增加时的调度器数量Nprev_rise;
7) 最小调度器数量Nmin;
确定活跃调度器数量的流程如下图所示。
迁移阈值
如果确定的活跃调度器数量小于当前在线调度器数量,说明当前负载较低,有部分调度器处于空闲状态,这部分调度器将会标记为inactive,然后其对应的任务队列上的任务会迁移到其它active调度器上。
如果确定的活跃调度器数量等于当前在线调度器数量,说明系统满载。会根据每个调度器任务队列运行情况,对每个优先级的任务队列都会计算一个可用性值(availability,avail):
1)
如果调度器在任务检查间隔内(2000*2000)一直处于等待状态,则avail=1;
2) 如果某个调度器所有优先队列上运行的reduction数量的和为0(未执行任务任务),那么这个调度器上所有优先队列的avail=0;
3) max和port优先队列的avail=1;
4) high、normal、low队列(normal和low共享一个队列,共享avail值)的avail按如下方式计算:
其中redpn为第n个调度器在所有优先队列上执行的reduction数量;redmax,n为第n个调度器在max队列上执行的reduction数量;redhigh,n为第n个调度器在high队列上执行的reduction数量。
5) 最后如果一个调度器在任务检查间隔内没有处于等待状态,则根据其所执行redcution数量的历史统计及该检查间隔内未处于等待状态队列的调度器个数对每个优先队列的avail做个调整。
最后,会根据每个优先队列的avail值及任务检查间隔内每个优先队列的最大队列长度(maxlength)为每个队列计算任务迁移阈值(migration_limit):
如果migration_limit ==0,则相应队列不需要迁入、迁出任务;如果不为0,则迁入、迁出任务的数量不能超过这个值。假设任务队列中只有normal优先级的任务(一般情况下,用户创建的进程都处于normal优先级),并且每个优先队列的avail值都相同,那么迁移阈值的计算就是对所有队列的最大长度的和做平均(如下图)。
确定每个队列的迁移路线
每个队列有了任务迁移的阈值后,根据其与相应调度器最大队列长度的差值,对队列由小到大进行排序(需要迁入的队列,差值为负,排在前面,迁出的排在后面)。排序后,队列尾(迁移任务者)对应到队列头(迁入任务者),依次确定为迁移路线:
比如在上面的图中,队列长度为14的任务将会迁移到队列长度为4的队列,队列长度为10的任务将会迁移到队列长度为5的队列。当然,一般情况下,肯定会有不匹配,如果有队列有多余的任务没有迁移完,则会从最小差值(上图队列长度为4)队列开始扫描,确定为迁移路线;如果有多余的队列需要迁入任务,则会从最大差值队列(队列长度为14)队列开始扫描,确定为迁移路线。如下图(有多余队列需要迁入任务)。
迁移路线确定后,在调度时,就会在相应的迁入、迁出队列之间传递任务,直到达到相应队列的迁入、迁出阈值。
最后,如果经过任务迁移逻辑后,当前的调度队列还是没有任务可以执行,调度器会尝试从其它调度队列偷一个任务过来(一般情况下,如果所有调度器都处于active状态,则会从最近的调度器偷取任务)。
- 大小: 40.4 KB
- 大小: 12 KB
- 大小: 10 KB
- 大小: 13 KB
- 大小: 22.6 KB
分享到:
相关推荐
Erlang并发编程,Erlang程序设计,Erlang中文手册。 学习erlang的好资料。 Erlang是一个结构化,动态类型编程语言,内建并行计算支持。最初是由爱立信专门为通信应用设计的,比如控制交换机或者变换协议等,因此...
erlang并发编程实战源代码erlang并发编程实战源代码
Erlang OTP并发编程实战高清非扫描版,基于一个simple cache深入浅出讲解erlang otp的使用。
erlang并发编程 .pdf
erlang并发编程,erlang之父Joe Armstrong得原著之一。
使用Erlang开发的微分进化算法。Erlang是一种函数式编程语言,非常适合于开发并行、分布式的应用
erlang otp学习文档 学习还不错的
erlang并发编程中文翻译(cpie-cn).zip
二十多年来,在传统电信领域高并发、高可靠、高容错的严酷环境下,Erlang语言和OTP平台被锻炼得坚如磐石,浓郁的函数式特质更是恰到好处地弥补了传统命令式语言在并发编程上的固有缺陷,大大降低了构筑并发、容错、...
Erlang OTP并发编程实战(中文版).pdf,不可多得的好书。
《erlang/otp并发编程实战》侧重生产环境下的erlang 开发,主要讲解如何构建稳定、版本控制良好、可维护的产品级代码,凝聚了三位erlang 大师多年的实战经验。 《erlang/otp并发编程实战》主要分为三大部分:第一...
erlang 入门书籍,与erlang程序设计相互认证着看,很不错
书是讲述下一代编程语言Erlang 的权威著作,主要涵盖顺序型编程、异常处理、编译和运行代码、并发编程、并发编程中的错误处理、分布式编程、多核编程等内容。本书将帮助读者在消息传递的基础上构建分布式的并发系统...
[Manning Publications] Erlang OTP 并发编程实战 (英文版) [Manning Publications] Erlang and OTP in Action (E-Book) ☆ 出版信息:☆ [作者信息] Martin Logan, Eric Merritt, Richard Carlsson [出版机构] ...
Erlang/OTP并发编程实战 英文
erlang的timer和实现机制 Erlang程序设计
Erlang OTP并发编程实战的附书源码,包括14章节里面的所有源码。
● 并发性 - Erlang支持超大量级的并发进程,并且不需要操作系统具有并发机制。 ● 分布式 - 一个分布式Erlang系统是多个Erlang节点组成的网络(通常每个处理器被作为一个节点) ● 健壮性 - Erlang具有多种基本的...
假设场景网格如下 数字代表的是坐标 11代表的是x1,y1 46代表的是 x4,y6 11, 12, 13, 14, 15, 16, 17, 18, 19 21, 22, 23, 24, 25, 26, 27, 28, 29 33, 32, 33, 34, 35, 36, 37, 38, 39 ...直接看代码吧erlang版