mirror of
https://github.com/ValveSoftware/GameNetworkingSockets.git
synced 2026-05-29 16:20:34 +00:00
Optimize per-packet stats tracking
- Don't increment counters every time we send or receive a packet, instead do a bit more work to decide if stats need to be sent. - Move some variables private
This commit is contained in:
@@ -282,8 +282,6 @@ struct LinkStatsTrackerBase
|
||||
inline void TrackSentPacket( int cbPktSize )
|
||||
{
|
||||
m_sent.ProcessPacket( cbPktSize );
|
||||
++m_nPktsSentSinceSentInstantaneous;
|
||||
++m_nPktsSentSinceSentLifetime;
|
||||
}
|
||||
|
||||
/// Consume the next sequence number, and record the time at which
|
||||
@@ -476,31 +474,10 @@ struct LinkStatsTrackerBase
|
||||
SteamDatagramLinkLifetimeStats m_lifetimeRemote;
|
||||
SteamNetworkingMicroseconds m_usecTimeRecvLifetimeRemote;
|
||||
|
||||
/// Local time when peer last acknowledged instantaneous stats.
|
||||
SteamNetworkingMicroseconds m_usecPeerAckedInstaneous;
|
||||
int64 m_pktNumInFlight;
|
||||
bool m_bInFlightInstantaneous;
|
||||
bool m_bInFlightLifetime;
|
||||
|
||||
/// Number of sequenced packets received since we last sent instantaneous stats
|
||||
int m_nPktsRecvSeqSinceSentInstantaneous;
|
||||
|
||||
/// Number of packets we have sent, since we last sent instantaneous stats
|
||||
int m_nPktsSentSinceSentInstantaneous;
|
||||
|
||||
/// Local time when we last sent lifetime stats.
|
||||
SteamNetworkingMicroseconds m_usecPeerAckedLifetime;
|
||||
|
||||
/// Number of sequenced packets received since we last sent lifetime stats
|
||||
int m_nPktsRecvSeqSinceSentLifetime;
|
||||
int m_nPktsSentSinceSentLifetime;
|
||||
|
||||
/// We sent lifetime stats on this seq number, has not been acknowledged. <0 if none
|
||||
//int m_seqnumUnackedSentLifetime;
|
||||
|
||||
/// We received lifetime stats at this sequence number, and should ack it soon. <0 if none
|
||||
//int m_seqnumPendingAckRecvTimelife;
|
||||
|
||||
/// Time when the current interval started
|
||||
SteamNetworkingMicroseconds m_usecIntervalStart;
|
||||
|
||||
@@ -545,14 +522,14 @@ struct LinkStatsTrackerBase
|
||||
inline void PeerAckedInstantaneous( SteamNetworkingMicroseconds usecNow )
|
||||
{
|
||||
m_usecPeerAckedInstaneous = usecNow;
|
||||
m_nPktsRecvSeqSinceSentInstantaneous = 0;
|
||||
m_nPktsSentSinceSentInstantaneous = 0;
|
||||
m_nPktsRecvSeqWhenPeerAckInstantaneous = m_nPktsRecvSequenced;
|
||||
m_nPktsSentWhenPeerAckInstantaneous = m_sent.m_packets.Total();
|
||||
}
|
||||
inline void PeerAckedLifetime( SteamNetworkingMicroseconds usecNow )
|
||||
{
|
||||
m_usecPeerAckedLifetime = usecNow;
|
||||
m_nPktsRecvSeqSinceSentLifetime = 0;
|
||||
m_nPktsSentSinceSentLifetime = 0;
|
||||
m_nPktsRecvSeqWhenPeerAckLifetime = m_nPktsRecvSequenced;
|
||||
m_nPktsSentWhenPeerAckLifetime = m_sent.m_packets.Total();
|
||||
}
|
||||
|
||||
void InFlightPktAck( SteamNetworkingMicroseconds usecNow )
|
||||
@@ -666,6 +643,19 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
// Number of lifetime sequenced packets received, and overall packets sent,
|
||||
// the last time the peer acked stats
|
||||
int64 m_nPktsRecvSeqWhenPeerAckInstantaneous;
|
||||
int64 m_nPktsSentWhenPeerAckInstantaneous;
|
||||
int64 m_nPktsRecvSeqWhenPeerAckLifetime;
|
||||
int64 m_nPktsSentWhenPeerAckLifetime;
|
||||
|
||||
/// Local time when peer last acknowledged lifetime stats.
|
||||
SteamNetworkingMicroseconds m_usecPeerAckedLifetime;
|
||||
|
||||
/// Local time when peer last acknowledged instantaneous stats.
|
||||
SteamNetworkingMicroseconds m_usecPeerAckedInstaneous;
|
||||
|
||||
bool BCheckHaveDataToSendInstantaneous( SteamNetworkingMicroseconds usecNow );
|
||||
bool BCheckHaveDataToSendLifetime( SteamNetworkingMicroseconds usecNow );
|
||||
|
||||
|
||||
@@ -309,12 +309,10 @@ bool LinkStatsTrackerBase::BCheckPacketNumberOldOrDuplicate( int64 nPktNum )
|
||||
// Update stats
|
||||
++m_nPktsRecvSequencedCurrentInterval;
|
||||
++m_nPktsRecvSequenced;
|
||||
++m_nPktsRecvSeqSinceSentLifetime;
|
||||
++m_nPktsRecvSeqSinceSentInstantaneous;
|
||||
|
||||
// Packet number is increasing?
|
||||
// (Maybe by a lot -- we don't handle that here.)
|
||||
if ( nPktNum > m_nMaxRecvPktNum )
|
||||
if ( likely( nPktNum > m_nMaxRecvPktNum ) )
|
||||
return true;
|
||||
|
||||
// Which block of 64-bit packets is it in?
|
||||
@@ -376,7 +374,7 @@ void LinkStatsTrackerBase::TrackProcessSequencedPacket( int64 nPktNum, SteamNetw
|
||||
// case will be packets delivered in order, we optimize this logic
|
||||
// for that case.
|
||||
int64 nGap = nPktNum - m_nMaxRecvPktNum;
|
||||
if ( nGap == 1 )
|
||||
if ( likely( nGap == 1 ) )
|
||||
{
|
||||
|
||||
// We've received two packets, in order. Did the sender supply the time between packets on his side?
|
||||
@@ -398,66 +396,64 @@ void LinkStatsTrackerBase::TrackProcessSequencedPacket( int64 nPktNum, SteamNetw
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
else if ( unlikely( nGap <= 0 ) )
|
||||
{
|
||||
// Classify imperfection based on gap size.
|
||||
if ( nGap >= 100 )
|
||||
// Packet number moving backward
|
||||
// We should have already rejected duplicates
|
||||
Assert( nGap != 0 );
|
||||
|
||||
// Packet number moving in reverse.
|
||||
// It should be a *small* negative step, e.g. packets delivered out of order.
|
||||
// If the packet is really old, we should have already discarded it earlier.
|
||||
Assert( nGap >= -8 * (int64)sizeof(m_recvPktNumberMask) );
|
||||
++m_nPktsRecvOutOfOrder;
|
||||
++m_nPktsRecvWeirdSequenceCurrentInterval;
|
||||
|
||||
// We previously counted this packet as dropped. Undo that, it wasn't dropped.
|
||||
if ( m_nPktsRecvDropped > 0 )
|
||||
{
|
||||
--m_nPktsRecvDropped;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is weird.
|
||||
AssertMsg8( false,
|
||||
"No dropped packets, pkt num %lld -> %lld, dup bit not set? recvseq=%lld, lurch=%lld, ooo=%lld, mask=[0x%llx, 0x%llx]. (%s)",
|
||||
(long long)m_nMaxRecvPktNum, (long long)nPktNum,
|
||||
(long long)m_nPktsRecvSequenced, (long long)m_nPktsRecvSequenceNumberLurch,
|
||||
(long long)m_nPktsRecvOutOfOrder,
|
||||
(unsigned long long)m_recvPktNumberMask[0], (unsigned long long)m_recvPktNumberMask[1],
|
||||
Describe().c_str()
|
||||
);
|
||||
}
|
||||
if ( m_nPktsRecvDroppedCurrentInterval > 0 ) // Might have marked it in the previous interval. Our stats will be slightly off in this case. Not worth it to try to get this exactly right.
|
||||
--m_nPktsRecvDroppedCurrentInterval;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Packet number moving forward, i.e. a dropped packet
|
||||
// Large gap?
|
||||
if ( unlikely( nGap >= 100 ) )
|
||||
{
|
||||
// Very weird.
|
||||
++m_nPktsRecvSequenceNumberLurch;
|
||||
++m_nPktsRecvWeirdSequenceCurrentInterval;
|
||||
|
||||
// Continue to code below, reseting the sequence number
|
||||
// for packets going forward.
|
||||
// Reset the sequence number for packets going forward.
|
||||
InitMaxRecvPktNum( nPktNum );
|
||||
return;
|
||||
}
|
||||
else if ( nGap > 0 )
|
||||
{
|
||||
// Probably the most common case, we just dropped a packet
|
||||
int nDropped = nGap-1;
|
||||
m_nPktsRecvDropped += nDropped;
|
||||
m_nPktsRecvDroppedCurrentInterval += nDropped;
|
||||
}
|
||||
else if ( nGap == 0 )
|
||||
{
|
||||
// We should have already rejected duplicates
|
||||
Assert( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Packet number moving in reverse.
|
||||
// It should be a *small* negative step, e.g. packets delivered out of order.
|
||||
// If the packet is really old, we should have already discarded it earlier.
|
||||
Assert( nGap >= -8 * (int64)sizeof(m_recvPktNumberMask) );
|
||||
++m_nPktsRecvOutOfOrder;
|
||||
++m_nPktsRecvWeirdSequenceCurrentInterval;
|
||||
|
||||
// We previously counted this packet as dropped. Undo that, it wasn't dropped.
|
||||
if ( m_nPktsRecvDropped > 0 )
|
||||
{
|
||||
--m_nPktsRecvDropped;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is weird.
|
||||
AssertMsg2( false,
|
||||
"No dropped packets, pkt num %lld -> %lld, dup bit not set? recvseq=%lld, lurch=%lld, ooo=%lld. (%s)",
|
||||
(long long)m_nMaxRecvPktNum, (long long)nPktNum,
|
||||
(long long)m_nPktsRecvSequenced, (long long)m_nPktsRecvSequenceNumberLurch,
|
||||
(long long)m_nPktsRecvOutOfOrder, Describe().c_str()
|
||||
);
|
||||
}
|
||||
if ( m_nPktsRecvDroppedCurrentInterval > 0 ) // Might have marked it in the previous interval. Our stats will be slightly off in this case. Not worth it tro try to get this exactly right.
|
||||
--m_nPktsRecvDroppedCurrentInterval;
|
||||
|
||||
}
|
||||
// Probably the most common case (after a perfect packet stream), we just dropped a packet or two
|
||||
int nDropped = nGap-1;
|
||||
m_nPktsRecvDropped += nDropped;
|
||||
m_nPktsRecvDroppedCurrentInterval += nDropped;
|
||||
}
|
||||
|
||||
// Save highest known sequence number for next time.
|
||||
if ( nGap > 0 )
|
||||
{
|
||||
m_nMaxRecvPktNum += nGap;
|
||||
m_usecTimeLastRecvSeq = usecNow;
|
||||
}
|
||||
m_nMaxRecvPktNum = nPktNum;
|
||||
m_usecTimeLastRecvSeq = usecNow;
|
||||
}
|
||||
|
||||
bool LinkStatsTrackerBase::BCheckHaveDataToSendInstantaneous( SteamNetworkingMicroseconds usecNow )
|
||||
@@ -474,8 +470,8 @@ bool LinkStatsTrackerBase::BCheckHaveDataToSendInstantaneous( SteamNetworkingMic
|
||||
Assert( usecElapsed >= k_usecLinkStatsInstantaneousReportMinInterval ); // don't call this unless you know it's been long enough!
|
||||
int nThreshold = usecElapsed / k_usecActiveConnectionSendInterval;
|
||||
|
||||
// Have they been trying to talk to us?
|
||||
if ( m_nPktsRecvSeqSinceSentInstantaneous > nThreshold || m_nPktsSentSinceSentInstantaneous > nThreshold )
|
||||
// Has there been any traffic worth reporting on in this interval?
|
||||
if ( m_nPktsRecvSeqWhenPeerAckInstantaneous + nThreshold < m_nPktsRecvSequenced || m_nPktsSentWhenPeerAckInstantaneous + nThreshold < m_sent.m_packets.Total() )
|
||||
return true;
|
||||
|
||||
// Connection has been idle since the last time we sent instantaneous stats.
|
||||
@@ -491,7 +487,7 @@ bool LinkStatsTrackerBase::BCheckHaveDataToSendLifetime( SteamNetworkingMicrosec
|
||||
Assert( !m_bPassive );
|
||||
|
||||
// Make sure we have something new to report since the last time we sent stats
|
||||
if ( m_nPktsRecvSeqSinceSentLifetime > 100 || m_nPktsSentSinceSentLifetime > 100 )
|
||||
if ( m_nPktsRecvSeqWhenPeerAckLifetime + 100 < m_nPktsRecvSequenced || m_nPktsSentWhenPeerAckLifetime + 100 < m_sent.m_packets.Total() )
|
||||
return true;
|
||||
|
||||
// Reset the timer. But do NOT reset the packet counters. So if the connection isn't
|
||||
|
||||
Reference in New Issue
Block a user