mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #7532 from Atlante45/feat/delayed-decrease
Delay congestion epochs first decrease
This commit is contained in:
commit
6025a66fa1
5 changed files with 34 additions and 24 deletions
|
@ -82,11 +82,11 @@ void AssetServer::completeSetup() {
|
|||
auto maxBandwidthFloat = maxBandwidthValue.toDouble(-1);
|
||||
|
||||
if (maxBandwidthFloat > 0.0) {
|
||||
const int BYTES_PER_MEGABITS = (1024 * 1024) / 8;
|
||||
int maxBandwidth = maxBandwidthFloat * BYTES_PER_MEGABITS;
|
||||
const int BITS_PER_MEGABITS = 1000 * 1000;
|
||||
int maxBandwidth = maxBandwidthFloat * BITS_PER_MEGABITS;
|
||||
nodeList->setConnectionMaxBandwidth(maxBandwidth);
|
||||
qInfo() << "Set maximum bandwith per connection to" << maxBandwidthFloat << "Mb/s."
|
||||
" (" << maxBandwidth << "bytes/sec)";
|
||||
" (" << maxBandwidth << "bits/s)";
|
||||
}
|
||||
|
||||
// get the path to the asset folder from the domain server settings
|
||||
|
|
|
@ -19,6 +19,7 @@ using namespace udt;
|
|||
using namespace std::chrono;
|
||||
|
||||
static const double USECS_PER_SECOND = 1000000.0;
|
||||
static const int BITS_PER_BYTE = 8;
|
||||
|
||||
void CongestionControl::setMaxBandwidth(int maxBandwidth) {
|
||||
_maxBandwidth = maxBandwidth;
|
||||
|
@ -28,11 +29,11 @@ void CongestionControl::setMaxBandwidth(int maxBandwidth) {
|
|||
void CongestionControl::setPacketSendPeriod(double newSendPeriod) {
|
||||
Q_ASSERT_X(newSendPeriod >= 0, "CongestionControl::setPacketPeriod", "Can not set a negative packet send period");
|
||||
|
||||
auto maxBandwidth = _maxBandwidth.load();
|
||||
if (maxBandwidth > 0) {
|
||||
auto packetsPerSecond = (double)_maxBandwidth / (BITS_PER_BYTE * _mss);
|
||||
if (packetsPerSecond > 0.0) {
|
||||
// anytime the packet send period is about to be increased, make sure it stays below the minimum period,
|
||||
// calculated based on the maximum desired bandwidth
|
||||
double minPacketSendPeriod = USECS_PER_SECOND / (((double) maxBandwidth) / _mss);
|
||||
double minPacketSendPeriod = USECS_PER_SECOND / packetsPerSecond;
|
||||
_packetSendPeriod = std::max(newSendPeriod, minPacketSendPeriod);
|
||||
} else {
|
||||
_packetSendPeriod = newSendPeriod;
|
||||
|
@ -145,17 +146,23 @@ void DefaultCC::onLoss(SequenceNumber rangeStart, SequenceNumber rangeEnd) {
|
|||
}
|
||||
|
||||
_loss = true;
|
||||
|
||||
++_nakCount;
|
||||
|
||||
static const double INTER_PACKET_ARRIVAL_INCREASE = 1.125;
|
||||
static const int MAX_DECREASES_PER_CONGESTION_EPOCH = 5;
|
||||
|
||||
// check if this NAK starts a new congestion period - this will be the case if the
|
||||
// NAK received occured for a packet sent after the last decrease
|
||||
if (rangeStart > _lastDecreaseMaxSeq) {
|
||||
_delayedDecrease = (rangeStart == rangeEnd);
|
||||
|
||||
_lastDecreasePeriod = _packetSendPeriod;
|
||||
|
||||
setPacketSendPeriod(ceil(_packetSendPeriod * INTER_PACKET_ARRIVAL_INCREASE));
|
||||
|
||||
if (!_delayedDecrease) {
|
||||
setPacketSendPeriod(ceil(_packetSendPeriod * INTER_PACKET_ARRIVAL_INCREASE));
|
||||
} else {
|
||||
_loss = false;
|
||||
}
|
||||
|
||||
// use EWMA to update the average number of NAKs per congestion
|
||||
static const double NAK_EWMA_ALPHA = 0.125;
|
||||
|
@ -177,10 +184,12 @@ void DefaultCC::onLoss(SequenceNumber rangeStart, SequenceNumber rangeEnd) {
|
|||
|
||||
_randomDecreaseThreshold = distribution(generator);
|
||||
}
|
||||
} else if ((_decreaseCount++ < MAX_DECREASES_PER_CONGESTION_EPOCH) && ((++_nakCount % _randomDecreaseThreshold) == 0)) {
|
||||
} else if (_delayedDecrease && _nakCount == 2) {
|
||||
setPacketSendPeriod(ceil(_packetSendPeriod * INTER_PACKET_ARRIVAL_INCREASE));
|
||||
} else if ((_decreaseCount++ < MAX_DECREASES_PER_CONGESTION_EPOCH) && ((_nakCount % _randomDecreaseThreshold) == 0)) {
|
||||
// there have been fewer than MAX_DECREASES_PER_CONGESTION_EPOCH AND this NAK matches the random count at which we
|
||||
// decided we would decrease the packet send period
|
||||
|
||||
|
||||
setPacketSendPeriod(ceil(_packetSendPeriod * INTER_PACKET_ARRIVAL_INCREASE));
|
||||
_lastDecreaseMaxSeq = _sendCurrSeqNum;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <PortableHighResolutionClock.h>
|
||||
|
||||
|
@ -61,7 +60,7 @@ protected:
|
|||
double _congestionWindowSize { 16.0 }; // Congestion window size, in packets
|
||||
|
||||
int _bandwidth { 0 }; // estimated bandwidth, packets per second
|
||||
std::atomic<int> _maxBandwidth { -1 }; // Maximum desired bandwidth, bytes per second
|
||||
std::atomic<int> _maxBandwidth { -1 }; // Maximum desired bandwidth, bits per second
|
||||
double _maxCongestionWindowSize { 0.0 }; // maximum cwnd size, in packets
|
||||
|
||||
int _mss { 0 }; // Maximum Packet Size, including all packet headers
|
||||
|
@ -124,6 +123,7 @@ private:
|
|||
int _randomDecreaseThreshold { 1 }; // random threshold on decrease by number of loss events
|
||||
int _avgNAKNum { 0 }; // average number of NAKs per congestion
|
||||
int _decreaseCount { 0 }; // number of decreases in a congestion epoch
|
||||
bool _delayedDecrease { false };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -354,7 +354,7 @@ void Socket::setCongestionControlFactory(std::unique_ptr<CongestionControlVirtua
|
|||
|
||||
|
||||
void Socket::setConnectionMaxBandwidth(int maxBandwidth) {
|
||||
qInfo() << "Setting socket's maximum bandwith to" << maxBandwidth << ". ("
|
||||
qInfo() << "Setting socket's maximum bandwith to" << maxBandwidth << "bps. ("
|
||||
<< _connectionsHash.size() << "live connections)";
|
||||
_maxBandwidth = maxBandwidth;
|
||||
for (auto& pair : _connectionsHash) {
|
||||
|
|
|
@ -57,13 +57,13 @@ const QCommandLineOption STATS_INTERVAL {
|
|||
};
|
||||
|
||||
const QStringList CLIENT_STATS_TABLE_HEADERS {
|
||||
"Send (P/s)", "Est. Max (P/s)", "RTT (ms)", "CW (P)", "Period (us)",
|
||||
"Send (Mb/s)", "Est. Max (Mb/s)", "RTT (ms)", "CW (P)", "Period (us)",
|
||||
"Recv ACK", "Procd ACK", "Recv LACK", "Recv NAK", "Recv TNAK",
|
||||
"Sent ACK2", "Sent Packets", "Re-sent Packets"
|
||||
};
|
||||
|
||||
const QStringList SERVER_STATS_TABLE_HEADERS {
|
||||
" Mb/s ", "Recv P/s", "Est. Max (P/s)", "RTT (ms)", "CW (P)",
|
||||
" Mb/s ", "Recv Mb/s", "Est. Max (Mb/s)", "RTT (ms)", "CW (P)",
|
||||
"Sent ACK", "Sent LACK", "Sent NAK", "Sent TNAK",
|
||||
"Recv ACK2", "Duplicates (P)"
|
||||
};
|
||||
|
@ -364,7 +364,11 @@ void UDTTest::handleMessage(std::unique_ptr<Message> message) {
|
|||
void UDTTest::sampleStats() {
|
||||
static bool first = true;
|
||||
static const double USECS_PER_MSEC = 1000.0;
|
||||
|
||||
static const double MEGABITS_PER_BYTE = 8.0 / 1000000.0;
|
||||
static const double MS_PER_SECOND = 1000.0;
|
||||
static const double PPS_TO_MBPS = 1500.0 * MEGABITS_PER_BYTE;
|
||||
|
||||
|
||||
if (!_target.isNull()) {
|
||||
if (first) {
|
||||
// output the headers for stats for our table
|
||||
|
@ -378,8 +382,8 @@ void UDTTest::sampleStats() {
|
|||
|
||||
// setup a list of left justified values
|
||||
QStringList values {
|
||||
QString::number(stats.sendRate).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.estimatedBandwith).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.sendRate * PPS_TO_MBPS).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.estimatedBandwith * PPS_TO_MBPS).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.rtt / USECS_PER_MSEC, 'f', 2).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.congestionWindowSize).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.packetSendPeriod).rightJustified(CLIENT_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
|
@ -408,16 +412,13 @@ void UDTTest::sampleStats() {
|
|||
|
||||
int headerIndex = -1;
|
||||
|
||||
static const double MEGABITS_PER_BYTE = 8.0 / 1000000.0;
|
||||
static const double MS_PER_SECOND = 1000.0;
|
||||
|
||||
double megabitsPerSecond = (stats.receivedBytes * MEGABITS_PER_BYTE * MS_PER_SECOND) / _statsInterval;
|
||||
|
||||
// setup a list of left justified values
|
||||
QStringList values {
|
||||
QString::number(megabitsPerSecond, 'f', 2).rightJustified(SERVER_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.receiveRate).rightJustified(SERVER_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.estimatedBandwith).rightJustified(SERVER_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.receiveRate * PPS_TO_MBPS).rightJustified(SERVER_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.estimatedBandwith * PPS_TO_MBPS).rightJustified(SERVER_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.rtt / USECS_PER_MSEC, 'f', 2).rightJustified(SERVER_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.congestionWindowSize).rightJustified(SERVER_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
QString::number(stats.events[udt::ConnectionStats::Stats::SentACK]).rightJustified(SERVER_STATS_TABLE_HEADERS[++headerIndex].size()),
|
||||
|
|
Loading…
Reference in a new issue