forked from Mirrorlandia_minetest/minetest
RTT fixes (#7428)
* Few code updates * Do not show average RTT before timing out * Fix unwanted integer division in RTTStatistics * Fix float format, prettier jitter calculation * Use +=, 0.1f -> 100.0f for stronger average updates
This commit is contained in:
parent
07b1743d3d
commit
968ce9af59
@ -437,7 +437,7 @@ void Client::step(float dtime)
|
|||||||
counter = 0.0;
|
counter = 0.0;
|
||||||
// connectedAndInitialized() is true, peer exists.
|
// connectedAndInitialized() is true, peer exists.
|
||||||
float avg_rtt = getRTT();
|
float avg_rtt = getRTT();
|
||||||
infostream << "Client: avg_rtt=" << avg_rtt << std::endl;
|
infostream << "Client: average rtt: " << avg_rtt << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1706,9 +1706,17 @@ void Client::afterContentReceived()
|
|||||||
delete[] text;
|
delete[] text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns the Round Trip Time
|
||||||
|
// if the RTT did not become updated within 2 seconds, e.g. before timing out,
|
||||||
|
// it returns the expired time instead
|
||||||
float Client::getRTT()
|
float Client::getRTT()
|
||||||
{
|
{
|
||||||
return m_con->getPeerStat(PEER_ID_SERVER,con::AVG_RTT);
|
float avg_rtt = m_con->getPeerStat(PEER_ID_SERVER, con::AVG_RTT);
|
||||||
|
float time_from_last_rtt =
|
||||||
|
m_con->getPeerStat(PEER_ID_SERVER, con::TIMEOUT_COUNTER);
|
||||||
|
if (avg_rtt + 2.0f > time_from_last_rtt)
|
||||||
|
return avg_rtt;
|
||||||
|
return time_from_last_rtt;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Client::getCurRate()
|
float Client::getCurRate()
|
||||||
|
@ -825,8 +825,9 @@ void Peer::DecUseCount()
|
|||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Peer::RTTStatistics(float rtt, const std::string &profiler_id,
|
void Peer::RTTStatistics(float rtt, const std::string &profiler_id)
|
||||||
unsigned int num_samples) {
|
{
|
||||||
|
static const float avg_factor = 100.0f / MAX_RELIABLE_WINDOW_SIZE;
|
||||||
|
|
||||||
if (m_last_rtt > 0) {
|
if (m_last_rtt > 0) {
|
||||||
/* set min max values */
|
/* set min max values */
|
||||||
@ -839,19 +840,12 @@ void Peer::RTTStatistics(float rtt, const std::string &profiler_id,
|
|||||||
if (m_rtt.avg_rtt < 0.0)
|
if (m_rtt.avg_rtt < 0.0)
|
||||||
m_rtt.avg_rtt = rtt;
|
m_rtt.avg_rtt = rtt;
|
||||||
else
|
else
|
||||||
m_rtt.avg_rtt = m_rtt.avg_rtt * (num_samples/(num_samples-1)) +
|
m_rtt.avg_rtt += (rtt - m_rtt.avg_rtt) * avg_factor;
|
||||||
rtt * (1/num_samples);
|
|
||||||
|
|
||||||
/* do jitter calculation */
|
/* do jitter calculation */
|
||||||
|
|
||||||
//just use some neutral value at beginning
|
//just use some neutral value at beginning
|
||||||
float jitter = m_rtt.jitter_min;
|
float jitter = std::fabs(rtt - m_last_rtt);
|
||||||
|
|
||||||
if (rtt > m_last_rtt)
|
|
||||||
jitter = rtt-m_last_rtt;
|
|
||||||
|
|
||||||
if (rtt <= m_last_rtt)
|
|
||||||
jitter = m_last_rtt - rtt;
|
|
||||||
|
|
||||||
if (jitter < m_rtt.jitter_min)
|
if (jitter < m_rtt.jitter_min)
|
||||||
m_rtt.jitter_min = jitter;
|
m_rtt.jitter_min = jitter;
|
||||||
@ -861,8 +855,7 @@ void Peer::RTTStatistics(float rtt, const std::string &profiler_id,
|
|||||||
if (m_rtt.jitter_avg < 0.0)
|
if (m_rtt.jitter_avg < 0.0)
|
||||||
m_rtt.jitter_avg = jitter;
|
m_rtt.jitter_avg = jitter;
|
||||||
else
|
else
|
||||||
m_rtt.jitter_avg = m_rtt.jitter_avg * (num_samples/(num_samples-1)) +
|
m_rtt.jitter_avg += (jitter - m_rtt.jitter_avg) * avg_factor;
|
||||||
jitter * (1/num_samples);
|
|
||||||
|
|
||||||
if (!profiler_id.empty()) {
|
if (!profiler_id.empty()) {
|
||||||
g_profiler->graphAdd(profiler_id + "_rtt", rtt);
|
g_profiler->graphAdd(profiler_id + "_rtt", rtt);
|
||||||
@ -934,16 +927,12 @@ void UDPPeer::setNonLegacyPeer()
|
|||||||
|
|
||||||
void UDPPeer::reportRTT(float rtt)
|
void UDPPeer::reportRTT(float rtt)
|
||||||
{
|
{
|
||||||
if (rtt < 0.0) {
|
assert(rtt >= 0.0f);
|
||||||
return;
|
|
||||||
}
|
RTTStatistics(rtt, "rudp");
|
||||||
RTTStatistics(rtt,"rudp",MAX_RELIABLE_WINDOW_SIZE*10);
|
|
||||||
|
|
||||||
float timeout = getStat(AVG_RTT) * RESEND_TIMEOUT_FACTOR;
|
float timeout = getStat(AVG_RTT) * RESEND_TIMEOUT_FACTOR;
|
||||||
if (timeout < RESEND_TIMEOUT_MIN)
|
timeout = rangelim(timeout, RESEND_TIMEOUT_MIN, RESEND_TIMEOUT_MAX);
|
||||||
timeout = RESEND_TIMEOUT_MIN;
|
|
||||||
if (timeout > RESEND_TIMEOUT_MAX)
|
|
||||||
timeout = RESEND_TIMEOUT_MAX;
|
|
||||||
|
|
||||||
MutexAutoLock usage_lock(m_exclusive_access_mutex);
|
MutexAutoLock usage_lock(m_exclusive_access_mutex);
|
||||||
resend_timeout = timeout;
|
resend_timeout = timeout;
|
||||||
|
@ -593,15 +593,15 @@ class Peer {
|
|||||||
return m_rtt.jitter_max;
|
return m_rtt.jitter_max;
|
||||||
case AVG_JITTER:
|
case AVG_JITTER:
|
||||||
return m_rtt.jitter_avg;
|
return m_rtt.jitter_avg;
|
||||||
|
case TIMEOUT_COUNTER:
|
||||||
|
return m_timeout_counter;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
virtual void reportRTT(float rtt) {};
|
virtual void reportRTT(float rtt) {};
|
||||||
|
|
||||||
void RTTStatistics(float rtt,
|
void RTTStatistics(float rtt, const std::string &profiler_id = "");
|
||||||
const std::string &profiler_id = "",
|
|
||||||
unsigned int num_samples = 1000);
|
|
||||||
|
|
||||||
bool IncUseCount();
|
bool IncUseCount();
|
||||||
void DecUseCount();
|
void DecUseCount();
|
||||||
|
@ -1167,20 +1167,17 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Control(Channel *chan
|
|||||||
|
|
||||||
// a overflow is quite unlikely but as it'd result in major
|
// a overflow is quite unlikely but as it'd result in major
|
||||||
// rtt miscalculation we handle it here
|
// rtt miscalculation we handle it here
|
||||||
|
float rtt;
|
||||||
if (current_time > p.absolute_send_time) {
|
if (current_time > p.absolute_send_time) {
|
||||||
float rtt = (current_time - p.absolute_send_time) / 1000.0;
|
rtt = (current_time - p.absolute_send_time) / 1000.0f;
|
||||||
|
|
||||||
// Let peer calculate stuff according to it
|
|
||||||
// (avg_rtt and resend_timeout)
|
|
||||||
dynamic_cast<UDPPeer *>(peer)->reportRTT(rtt);
|
|
||||||
} else if (p.totaltime > 0) {
|
} else if (p.totaltime > 0) {
|
||||||
float rtt = p.totaltime;
|
rtt = p.totaltime;
|
||||||
|
}
|
||||||
|
|
||||||
// Let peer calculate stuff according to it
|
// Let peer calculate stuff according to it
|
||||||
// (avg_rtt and resend_timeout)
|
// (avg_rtt and resend_timeout)
|
||||||
dynamic_cast<UDPPeer *>(peer)->reportRTT(rtt);
|
dynamic_cast<UDPPeer *>(peer)->reportRTT(rtt);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// put bytes for max bandwidth calculation
|
// put bytes for max bandwidth calculation
|
||||||
channel->UpdateBytesSent(p.data.getSize(), 1);
|
channel->UpdateBytesSent(p.data.getSize(), 1);
|
||||||
if (channel->outgoing_reliables_sent.size() == 0)
|
if (channel->outgoing_reliables_sent.size() == 0)
|
||||||
|
@ -30,7 +30,8 @@ typedef enum {
|
|||||||
AVG_RTT,
|
AVG_RTT,
|
||||||
MIN_JITTER,
|
MIN_JITTER,
|
||||||
MAX_JITTER,
|
MAX_JITTER,
|
||||||
AVG_JITTER
|
AVG_JITTER,
|
||||||
|
TIMEOUT_COUNTER
|
||||||
} rtt_stat_type;
|
} rtt_stat_type;
|
||||||
|
|
||||||
class Peer;
|
class Peer;
|
||||||
|
Loading…
Reference in New Issue
Block a user