Browse Source

Reduced how often relative path qualities and aggregate link allocations are computed

Joseph Henry 7 năm trước cách đây
mục cha
commit
0faa655b83
4 tập tin đã thay đổi với 38 bổ sung24 xóa
  1. 1 2
      node/Constants.hpp
  2. 17 2
      node/Path.hpp
  3. 15 18
      node/Peer.cpp
  4. 5 2
      node/Peer.hpp

+ 1 - 2
node/Constants.hpp

@@ -305,8 +305,7 @@
 #define ZT_PATH_LATENCY_SAMPLE_INTERVAL ZT_MULTIPATH_PEER_PING_PERIOD * 2
 
 /**
- * Interval used for rate-limiting the computation of path quality estimates. Set at 0
- * to compute as new packets arrive with no delay.
+ * Interval used for rate-limiting the computation of path quality estimates.
  */
 #define ZT_PATH_QUALITY_COMPUTE_INTERVAL 1000
 

+ 17 - 2
node/Path.hpp

@@ -119,7 +119,8 @@ public:
 		_packetErrorRatio(0.0),
 		_packetLossRatio(0),
 		_lastComputedStability(0.0),
-		_lastComputedRelativeQuality(0)
+		_lastComputedRelativeQuality(0),
+		_lastAllocation(0.0)
 	{
 		prepareBuffers();
 	}
@@ -149,7 +150,8 @@ public:
 		_packetErrorRatio(0.0),
 		_packetLossRatio(0),
 		_lastComputedStability(0.0),
-		_lastComputedRelativeQuality(0)
+		_lastComputedRelativeQuality(0),
+		_lastAllocation(0.0)
 	{
 		prepareBuffers();
 		_phy->getIfName((PhySocket *)((uintptr_t)_localSocket), _ifname, 16);
@@ -518,6 +520,18 @@ public:
 	 */
 	inline float relativeQuality() { return _lastComputedRelativeQuality; }
 
+	/**
+	 * Assign a new allocation value for this path in the aggregate link
+	 *
+	 * @param allocation Percentage of traffic to be sent over this path to a peer
+	 */
+	inline void updateComponentAllocationOfAggregateLink(float allocation) { _lastAllocation = allocation; }
+
+	/**
+	 * @return Percentage of traffic allocated to this path in the aggregate link
+	 */
+	inline float allocation() { return _lastAllocation; }
+
 	/**
 	 * @return Stability estimates can become expensive to compute, we cache the most recent result.
 	 */
@@ -682,6 +696,7 @@ private:
 	// cached estimates
 	float _lastComputedStability;
 	float _lastComputedRelativeQuality;
+	float _lastAllocation;
 
 	// cached human-readable strings for tracing purposes
 	char _ifname[16];

+ 15 - 18
node/Peer.cpp

@@ -66,7 +66,8 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident
 	_linkIsBalanced(false),
 	_linkIsRedundant(false),
 	_remotePeerMultipathEnabled(false),
-	_lastAggregateStatsReport(0)
+	_lastAggregateStatsReport(0),
+	_lastAggregateAllocation(0)
 {
 	if (!myIdentity.agree(peerIdentity,_key,ZT_PEER_SECRET_KEY_LENGTH))
 		throw ZT_EXCEPTION_INVALID_ARGUMENT;
@@ -289,7 +290,7 @@ void Peer::recordIncomingPacket(void *tPtr, const SharedPtr<Path> &path, const u
 	}
 }
 
-float Peer::computeAggregateLinkRelativeQuality(int64_t now)
+void Peer::computeAggregateProportionalAllocation(int64_t now)
 {
 	float maxStability = 0;
 	float totalRelativeQuality = 0;
@@ -326,7 +327,12 @@ float Peer::computeAggregateLinkRelativeQuality(int64_t now)
 			_paths[i].p->updateRelativeQuality(relQuality);
 		}
 	}
-	return (float)1.0 / totalRelativeQuality; // Used later to convert relative quantities into flow allocations
+	// Convert set of relative performances into an allocation set
+	for(uint16_t i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
+		if (_paths[i].p) {
+			_paths[i].p->updateComponentAllocationOfAggregateLink(_paths[i].p->relativeQuality() / totalRelativeQuality);
+		}
+	}
 }
 
 float Peer::computeAggregateLinkPacketDelayVariance()
@@ -453,8 +459,6 @@ SharedPtr<Path> Peer::getAppropriatePath(int64_t now, bool includeExpired)
 	 * Proportionally allocate traffic according to dynamic path quality measurements
 	 */
 	if (RR->node->getMultipathMode() == ZT_MULTIPATH_PROPORTIONALLY_BALANCED) {
-		float alloc[ZT_MAX_PEER_NETWORK_PATHS];
-		memset(&alloc, 0, sizeof(alloc));
 		int numAlivePaths = 0;
 		int numStalePaths = 0;
 		int alivePaths[ZT_MAX_PEER_NETWORK_PATHS];
@@ -476,34 +480,27 @@ SharedPtr<Path> Peer::getAppropriatePath(int64_t now, bool includeExpired)
 				bestPath = i;
 			}
 		}
-
-				// Compare paths to each-other
-		float qualityScalingFactor = computeAggregateLinkRelativeQuality(now);
-
+		if ((now - _lastAggregateAllocation) >= ZT_PATH_QUALITY_COMPUTE_INTERVAL) {
+			_lastAggregateAllocation = now;
+			computeAggregateProportionalAllocation(now);
+		}
 		if (numAlivePaths == 0 && numStalePaths == 0) {
 			return SharedPtr<Path>();
 		} if (numAlivePaths == 1 || numStalePaths == 1) {
 			return _paths[bestPath].p;
 		}
-
-		// Convert set of relative performances into an allocation set
-		for(uint16_t i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
-			if (_paths[i].p) {
-				alloc[i] = _paths[i].p->relativeQuality() * qualityScalingFactor;
-			}
-		}
 		// Randomly choose path according to their allocations
 		unsigned int r;
 		Utils::getSecureRandom(&r, 1);
 		float rf = (float)(r %= 100) / 100;
 		for(int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
 			if (_paths[i].p) {
-				if (rf < alloc[i]) {
+				if (rf < _paths[i].p->allocation()) {
 					bestPath = i;
 					_pathChoiceHist->push(bestPath); // Record which path we chose
 					break;
 				}
-				rf -= alloc[i];
+				rf -= _paths[i].p->allocation();
 			}
 		}
 		if (bestPath < ZT_MAX_PEER_NETWORK_PATHS) {

+ 5 - 2
node/Peer.hpp

@@ -194,9 +194,11 @@ public:
 	void sendQOS_MEASUREMENT(void *tPtr, const SharedPtr<Path> &path, const int64_t localSocket,const InetAddress &atAddress,int64_t now);
 
 	/**
-	 * @return The relative quality values for each path
+	 * Compute relative quality values and allocations for the components of the aggregate link
+	 *
+	 * @param now Current time
 	 */
-	float computeAggregateLinkRelativeQuality(int64_t now);
+	void computeAggregateProportionalAllocation(int64_t now);
 
 	/**
 	 * @return The aggregate link Packet Delay Variance (PDV)
@@ -677,6 +679,7 @@ private:
 	bool _remotePeerMultipathEnabled;
 
 	uint64_t _lastAggregateStatsReport;
+	uint64_t _lastAggregateAllocation;
 
 	char _interfaceListStr[256]; // 16 characters * 16 paths in a link
 };