[tor-commits] [torflow/master] Allow desc bw to be used in feedback.

mikeperry at torproject.org mikeperry at torproject.org
Thu Nov 17 23:50:09 UTC 2011


commit 0e9738d8d5670472ae0e503629f1bbfca3ff6d9b
Author: Mike Perry <mikeperry-git at fscked.org>
Date:   Tue Nov 15 21:06:34 2011 -0800

    Allow desc bw to be used in feedback.
    
    It may be equivalent to NS bw, since the NS bw functions as an accumulator..
    We may want to set T_i_decay to 0 for this code.
---
 NetworkScanners/BwAuthority/aggregate.py |   76 +++++++++++++++++++++--------
 1 files changed, 55 insertions(+), 21 deletions(-)

diff --git a/NetworkScanners/BwAuthority/aggregate.py b/NetworkScanners/BwAuthority/aggregate.py
index fb5cc7a..c55b9a1 100755
--- a/NetworkScanners/BwAuthority/aggregate.py
+++ b/NetworkScanners/BwAuthority/aggregate.py
@@ -88,6 +88,7 @@ class Node:
     self.ratio = None
     self.new_bw = None
     self.change = None
+    self.use_bw = -1
 
     # measurement vars from bwauth lines
     self.measured_at = 0
@@ -100,24 +101,32 @@ class Node:
     self.updated_at = 0
 
   def revert_to_vote(self, vote):
-    self.new_bw = vote.bw*1000
-    self.pid_bw = vote.pid_bw
-    self.pid_error = vote.pid_error
-    self.pid_error_sum = vote.pid_error_sum
-    self.pid_delta = vote.pid_delta
-    self.measured_at = vote.measured_at
-
-  # Derivative of error for pid control
-  def get_pid_bw(self, prev_vote, kp, ki, kd, kidecay):
+    self.copy_vote(vote)
+    self.pid_error = vote.pid_error # Set
+    self.measured_at = vote.measured_at # Set
+
+  def copy_vote(self, vote):
+    self.new_bw = vote.bw*1000 # Not set yet
+    self.pid_bw = vote.pid_bw  # Not set yet
+    self.pid_error_sum = vote.pid_error_sum # Not set yet
+    self.pid_delta = vote.pid_delta # Not set yet
+
+  def get_pid_bw(self, prev_vote, kp, ki, kd, kidecay, update=True):
+    if not update:
+      return self.use_bw \
+                  + kp*self.use_bw*self.pid_error \
+                  + ki*self.use_bw*self.pid_error_sum \
+                  + kd*self.use_bw*self.pid_delta
+
     self.prev_error = prev_vote.pid_error
     # We decay the interval each round to keep it bounded.
     # This decay is non-standard. We do it to avoid overflow
     self.pid_error_sum = prev_vote.pid_error_sum*kidecay + self.pid_error
 
-    self.pid_bw = self.ns_bw \
-                             + kp*self.ns_bw*self.pid_error \
-                             + ki*self.ns_bw*self.integral_error() \
-                             + kd*self.ns_bw*self.d_error_dt()
+    self.pid_bw = self.use_bw \
+                             + kp*self.use_bw*self.pid_error \
+                             + ki*self.use_bw*self.integral_error() \
+                             + kd*self.use_bw*self.d_error_dt()
     return self.pid_bw
 
   # Time-weighted sum of error per unit of time (measurement sample)
@@ -212,6 +221,7 @@ class ConsensusJunk:
     self.bwauth_pid_control = False
     self.use_circ_fails = False
     self.use_best_ratio = False
+    self.use_desc_bw = False
 
     self.K_p = K_p
     self.T_i = T_i
@@ -224,6 +234,9 @@ class ConsensusJunk:
       for p in cs_params:
         if p == "bwauthpid=1":
           self.bwauth_pid_control = True
+        elif p == "bwauthdescbw=1":
+          self.use_desc_bw = True
+          plog("INFO", "Using descriptor bandwidth")
         elif p == "bwauthcircs=1":
           self.use_circ_fails = True
           plog("INFO", "Counting circuit failures")
@@ -472,6 +485,11 @@ def main(argv):
     n.sbw_ratio = n.strm_bw/true_strm_avg
 
     if cs_junk.bwauth_pid_control:
+      if cs_junk.use_desc_bw:
+        n.use_bw = n.desc_bw
+      else:
+        n.use_bw = n.ns_bw
+
       # Penalize nodes for circ failure rate
       if cs_junk.use_best_ratio and n.sbw_ratio > n.fbw_ratio:
         n.pid_error = (n.strm_bw*(1.0-n.circ_fail_rate) - true_strm_avg)/true_strm_avg
@@ -496,13 +514,28 @@ def main(argv):
                                       cs_junk.K_d,
                                       cs_junk.K_i_decay)
             else:
-              pid_error = n.pid_error
-              n.revert_to_vote(prev_votes.vote_map[n.idhex])
               # Don't use feedback here, but we might as well use our
               # new measurement against the previous vote.
-              n.new_bw = prev_votes.vote_map[n.idhex].pid_bw + \
-                       cs_junk.K_p*prev_votes.vote_map[n.idhex].pid_bw*pid_error
-
+              n.copy_vote(prev_votes.vote_map[n.idhex])
+
+              if cs_junk.use_desc_bw:
+                n.new_bw = n.get_pid_bw(prev_votes.vote_map[n.idhex],
+                                    cs_junk.K_p,
+                                    cs_junk.K_i,
+                                    cs_junk.K_d,
+                                    0.0, False)
+              else:
+                # Use previous vote's feedback bw
+                n.use_bw = prev_votes.vote_map[n.idhex].pid_bw
+                n.new_bw = n.get_pid_bw(prev_votes.vote_map[n.idhex],
+                                    cs_junk.K_p,
+                                    0.0,
+                                    0.0,
+                                    0.0, False)
+
+              # Reset the remaining vote data..
+              n.measured_at = prev_votes.vote_map[n.idhex].measured_at
+              n.pid_error = prev_votes.vote_map[n.idhex].pid_error
           else:
             # Everyone else should be pretty instantenous to respond.
             # Full feedback should be fine for them (we hope),
@@ -529,7 +562,7 @@ def main(argv):
           # Reset values. Don't vote/sample this measurement round.
           n.revert_to_vote(prev_votes.vote_map[n.idhex])
       else: # No prev vote, pure consensus feedback this round
-        n.new_bw = n.ns_bw + cs_junk.K_p*n.ns_bw*n.pid_error
+        n.new_bw = n.use_bw + cs_junk.K_p*n.use_bw*n.pid_error
         n.pid_error_sum = n.pid_error
         n.pid_bw = n.new_bw
         plog("INFO", "No prev vote for node "+n.nick+": Consensus feedback")
@@ -565,8 +598,9 @@ def main(argv):
     if n.new_bw >= 0xffffffff*1000:
       plog("WARN", "Bandwidth of node "+n.nick+"="+n.idhex+" exceeded maxint32: "+str(n.new_bw))
       n.new_bw = 0xffffffff*1000
-    if cs_junk.T_i > 0 and math.fabs(n.pid_error_sum) > \
-       math.fabs(2*cs_junk.T_i*n.pid_error/cs_junk.T_i_decay):
+    if cs_junk.T_i > 0 and cs_junk.T_i_decay > 0 \
+       and math.fabs(n.pid_error_sum) > \
+           math.fabs(2*cs_junk.T_i*n.pid_error/cs_junk.T_i_decay):
       plog("NOTICE", "Large pid_error_sum for node "+n.idhex+"="+n.nick+": "+
                    str(n.pid_error_sum)+" vs "+str(n.pid_error))
     if n.new_bw > tot_net_bw*NODE_CAP:





More information about the tor-commits mailing list