Browse Source

Restored original sendrate decrease logic.

Lasse Öörni 14 years ago
parent
commit
ba533b449c

+ 1 - 1
Engine/Network/Connection.cpp

@@ -43,7 +43,7 @@
 
 #include "DebugNew.h"
 
-static const int STATS_INTERVAL_MSEC = 1000;
+static const int STATS_INTERVAL_MSEC = 2000;
 static const String noName;
 
 PackageDownload::PackageDownload() :

+ 1 - 0
ThirdParty/kNet/include/kNet/UDPMessageConnection.h

@@ -149,6 +149,7 @@ private:
 
 	/// The flow control algorithm:
 	float datagramSendRate; ///< The number of datagrams/second to send.
+	float lowestDatagramSendRateOnPacketLoss;
 	int slowModeDelay; ///< Go into slow increase mode for some time on receiving loss
 
 	// These variables correspond to RFC2988, http://tools.ietf.org/html/rfc2988 , section 2.

+ 26 - 14
ThirdParty/kNet/src/UDPMessageConnection.cpp

@@ -154,7 +154,7 @@ void UDPMessageConnection::Initialize()
 	retransmissionTimeout = 1000.f;
 	smoothedRTT = 1000.f;
 	rttVariation = 0.f;
-	datagramSendRate = 50.f;
+	datagramSendRate = lowestDatagramSendRateOnPacketLoss = 50.f;
 
 	lastFrameTime = Clock::Tick();
 	lastDatagramSendTime = Clock::Tick();
@@ -240,6 +240,9 @@ void UDPMessageConnection::ProcessPacketTimeouts() // [worker thread]
 			(int)track->packetID, (float)Clock::TimespanToMillisecondsD(track->sentTick, now), (int)track->messages.size());
 		ADDEVENT("datagramsLost", 1, "");
 
+		// Store a new suggestion for a lowered datagram send rate.
+		lowestDatagramSendRateOnPacketLoss = min(lowestDatagramSendRateOnPacketLoss, track->datagramSendRate);
+
 		// Adjust the flow control values on this event.
 		UpdateRTOCounterOnPacketLoss();
 
@@ -265,7 +268,7 @@ void UDPMessageConnection::HandleFlowControl()
 	const float minBandwidthOnLoss = 10.f;
 	const float minBandwidth = 50.f;
 	const float maxBandwidth = 10000.f;
-	const int framesPerSec = 30;
+	const int framesPerSec = 10;
 	const int maxSlowModeDelay = 10 * framesPerSec;
 
 	const tick_t frameLength = Clock::TicksPerSec() / framesPerSec; // in ticks
@@ -276,14 +279,18 @@ void UDPMessageConnection::HandleFlowControl()
 	{
 		if (numFrames >= framesPerSec)
 			numFrames = framesPerSec;
-			
+
 		int numUnacked = NumOutboundUnackedDatagrams();
-		
-		// Reduce sendrate and go to slow increase mode on loss
-		if (numLossesLastFrame > 0)
+
+		// Reduce sendrate and/or go to slow mode on loss
+		if (numLossesLastFrame > 1)
 		{
-			float multiplier = max(1.f - numLossesLastFrame * 0.01f, 0.95f);
-			datagramSendRate = max(datagramSendRate * multiplier, minBandwidthOnLoss);
+			if (numLossesLastFrame > 2)
+			{
+				float oldRate = datagramSendRate;
+				datagramSendRate = min(datagramSendRate, max(minBandwidthOnLoss, lowestDatagramSendRateOnPacketLoss * 0.9f)); // Multiplicative decreases.
+				LOG(LogVerbose, "Received %d losses. datagramSendRate backed to %.2f from %.2f", (int)numLossesLastFrame, datagramSendRate, oldRate);
+			}
 			slowModeDelay = min(slowModeDelay + numLossesLastFrame * framesPerSec, maxSlowModeDelay);
 		}
 		else
@@ -292,24 +299,29 @@ void UDPMessageConnection::HandleFlowControl()
 			///\todo Very simple logic for now, can be improved
 			bool needMore = outboundQueue.Size() > 10;
 			bool needLess = outboundQueue.Size() == 0;
-			
+			float maxRTT = max(rtt, smoothedRTT);
+
 			// Need more: increase sendrate. Factor in RTT and acks
-			if (needMore)
+			if (needMore && numLossesLastFrame == 0)
 			{
-				float maxRTT = max(rtt, smoothedRTT);
-				float delta = (50.f + numAcksLastFrame) / maxRTT;
+				float delta = (50.f + 2.f * numAcksLastFrame) / maxRTT;
 				if (slowModeDelay > 0)
 					delta *= 0.2f;
 				datagramSendRate = min(datagramSendRate + delta, maxBandwidth);
+				lowestDatagramSendRateOnPacketLoss = datagramSendRate;
 			}
 			// Need less: decrease sendrate if not already at minimum
 			else if (needLess && datagramSendRate > minBandwidth)
 				datagramSendRate = max(datagramSendRate * 0.98f, minBandwidth);
+
+			// Whenever RTT is more than the minimum RTO value, back off slowly
+			//if (maxRTT > minRTOTimeoutValue && datagramSendRate > minBandwidth)
+			//	datagramSendRate = max(datagramSendRate * 0.999f, minBandwidth);
 		}
-		
+
 		if (slowModeDelay > 0)
 			--slowModeDelay;
-		
+
 		numAcksLastFrame = 0;
 		numLossesLastFrame = 0;
 		lastFrameTime = now;