加权轮询算法

加权轮询（ Weighted round robin ）是网络中用于调度数据流的算法，也可用于调度进程。

加权轮询是轮询调度的一般化。加权轮询在队列或一系列任务上循环，每个轮次中各数据包或进程按权重获得运行机会。

加权轮询有若干种类，比如经典加权轮询和交替加权轮询。

 算法 
下面以网络调度程序为例介绍加权轮询。

假设有个输入队列。每个队列的权重是一个正整数。使用加权轮询时，队列运行过程有周期性。在每个周期中，队列有次发送机会。

不同的加权轮询算法的区别是在一个周期中如何分配机会。

 经典加权轮询 
采用经典加权轮询算法时，调度程序会在队列间循环。轮到队列时，调度程序开始发送数据包，直到发出个数据包或遇到队尾为止。
 常量和变量: 
     const N             // 队列数 N
     const weight[1..N]  // 每个队列的权重
     queues[1..N]        // 队列
     i                   // 队列序号
     c                   // 数据包计数器

 指令:
 while true do 
    for i in 1 .. N do
       c:= 0
       while (not queue[i].empty) and (c<weight[i]) do
          send( queue[i].head() )
          queue[i].dequeue()
          c:= c+1

 交替加权轮询 
令为所有队列中的最大权重。在交替加权轮询算法中，每个周期分为轮。第轮中，如果，队列i可以发送一个数据包。
 常量和变量: 
     const N             // 队列数 N 
     const weight[1..N]  // 每个队列的权重
     const w_max
     queues[1..N]        // 队列
     i                   // 队列序号
     r                   // 轮次计数器

 指令:
 while true do
    for r in 1 .. w_max do 
       for i in 1 .. N do
          if (not queue[i].empty) and (weight[1..N] >= r)then
             send( queue[i].head() )
             queue[i].dequeue()

 示例 
居中|缩略图|经典加权轮询（CWRR）和交替加权轮询（IWRR）的调度示例
假设一个系统有三个队列, 其各自的权重。第一个队列中有7个数据包A，B，C，D，E，F，G，第二队列中为3个数据包U，V，W，第三个队列中有两个数据包X，Y。且不会有新数据包到达。

如果使用经典加权轮询算法，在第一个周期中，调度程序首先选择并传送位于队列头部的A，B，C，D，E（因为），然后选择第二个队列 ，传送队列开头的U，V（因为），最后选择第三个队列，该队列的权重等于3，然而该队列一共只有两个数据包，因此传输X，Y 。在Y的传输完毕后，第二个周期开始，先是发送中的F，G，然后是中的W。

如果使用交替加权轮询算法，第一个周期分为5轮。第一轮（r = 1），每个队列发送一个数据包（A，U，X），第二轮（r = 2），每个队列再发送一个数据包（B，V，Y），第三轮（r = 3），仅排队被允许发送数据包（， 和 ），但由于为空，只有来自的C被发送，在第四和第五轮，只有D，E从被发送。然后开始第二个周期，依次发送F，W，G。

 任务调度 
与数据包调度类似，加权轮询完成任务或进程调度时：个现行任务以循环方式安排，每个任务得到份的处理器时间 。

 性质 
调度数据包时，如果所有数据包都具有相同的大小，则WRR是通用处理器共享算法的近似：长期来看，队列将占据的带宽（假设所有队列均处于现行状态）。

如果数据包长度可变，则每个队列接收的带宽部分不仅取决于权重，还取决于数据包大小。

如果队列的平均数据包大小是，则每个队列将获得的长期带宽份额等于 。如果目标是给每个队列分配链接容量的（  ），则可以设置权重。

 参考文献 

Category:網路排程演算法