From d4adee8b388d6c2cb482f8e0792316892594a68c Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Thu, 23 Feb 2017 00:15:07 -0800 Subject: [PATCH] add over bandwidth exit to sorted avatar loop --- assignment-client/src/avatars/AvatarMixer.cpp | 10 ++++++-- .../src/avatars/AvatarMixerSlave.cpp | 23 +++++++++++++++---- .../src/avatars/AvatarMixerSlave.h | 3 +++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index a90fdb100c..6db9d05234 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -508,6 +508,9 @@ void AvatarMixer::sendStatsPacket() { float averageRandomDrops = averageNodes ? stats.randomDrops / averageNodes : 0.0f; slaveObject["sent_7_averageRandomDrops"] = TIGHT_LOOP_STAT(averageRandomDrops); + + float averageOverBudgetAvatars = averageNodes ? stats.overBudgetAvatars / averageNodes : 0.0f; + slaveObject["sent_8_averageOverBudgetAvatars"] = TIGHT_LOOP_STAT(averageOverBudgetAvatars); slaveObject["timing_1_processIncomingPackets"] = TIGHT_LOOP_STAT_UINT64(stats.processIncomingPacketsElapsedTime); slaveObject["timing_2_ignoreCalculation"] = TIGHT_LOOP_STAT_UINT64(stats.ignoreCalculationElapsedTime); @@ -536,11 +539,14 @@ void AvatarMixer::sendStatsPacket() { float averageOutboundAvatarKbps = averageNodes ? ((aggregateStats.numBytesSent / secondsSinceLastStats) / BYTES_PER_KILOBIT) / averageNodes : 0.0f; slavesAggregatObject["sent_5_averageOutboundAvatarKbps"] = averageOutboundAvatarKbps; + float averageOthersIncluded = averageNodes ? aggregateStats.numOthersIncluded / averageNodes : 0.0f; + slavesAggregatObject["sent_6_averageOthersIncluded"] = TIGHT_LOOP_STAT(averageOthersIncluded); + float averageRandomDrops = averageNodes ? aggregateStats.randomDrops / averageNodes : 0.0f; slavesAggregatObject["sent_7_averageRandomDrops"] = TIGHT_LOOP_STAT(averageRandomDrops); - float averageOthersIncluded = averageNodes ? aggregateStats.numOthersIncluded / averageNodes : 0.0f; - slavesAggregatObject["sent_6_averageOthersIncluded"] = TIGHT_LOOP_STAT(averageOthersIncluded); + float averageOverBudgetAvatars = averageNodes ? aggregateStats.overBudgetAvatars / averageNodes : 0.0f; + slavesAggregatObject["sent_8_averageOverBudgetAvatars"] = TIGHT_LOOP_STAT(averageOverBudgetAvatars); slavesAggregatObject["timing_1_processIncomingPackets"] = TIGHT_LOOP_STAT_UINT64(aggregateStats.processIncomingPacketsElapsedTime); slavesAggregatObject["timing_2_ignoreCalculation"] = TIGHT_LOOP_STAT_UINT64(aggregateStats.ignoreCalculationElapsedTime); diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 5073aab934..21eaebc176 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -129,6 +129,11 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { // keep track of outbound data rate specifically for avatar data int numAvatarDataBytes = 0; + // max number of avatarBytes per frame + auto maxAvatarBytesPerFrame = (_maxKbpsPerNode * BYTES_PER_KILOBIT) / AVATAR_MIXER_BROADCAST_FRAMES_PER_SECOND; + + int overBudgetAvatars = 0; + // keep track of the number of other avatars held back in this frame int numAvatarsHeldBack = 0; @@ -333,10 +338,10 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { // NOTE: If the recieving node is in "PAL mode" then it's asked to get things even that // are out of view, this also appears to disable this random distribution. // - // FIXME - This approach for managing the outbound bandwidth is less than ideal, - // it would be better to more directly budget the number of bytes to send - // per frame and simply exit the sorted avatar list once that budget is - // surpassed. We will work on that next. [BHG 2/22/17] + // FIXME - This is the old approach for managing the outbound bandwidth. I've left it + // in for now, even though we're also directly managing budget by calculating the + // number of bytes to send per frame and simply exiting the sorted avatar list + // once that budget is surpassed. I need to remove this old logic next. [BHG 2/22/17] if (distanceToAvatar != 0.0f && !getsOutOfView && distribution(generator) > (nodeData->getFullRateDistance() / distanceToAvatar) @@ -372,6 +377,16 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { ++numAvatarsWithSkippedFrames; } + // NOTE: Here's where we determine if we are over budget and stop considering avatars after this. + // + // FIXME - revisit this code, remove the random drop logic, and move this code higher up into + // the loop so we don't bother with all these other calculations once over budget. [BHG 2/22/17] + if (numAvatarDataBytes > maxAvatarBytesPerFrame) { + overBudgetAvatars++; + _stats.overBudgetAvatars++; + shouldConsider = false; + } + // we're going to send this avatar if (shouldConsider) { diff --git a/assignment-client/src/avatars/AvatarMixerSlave.h b/assignment-client/src/avatars/AvatarMixerSlave.h index 50ae4570b5..1bbd367b2b 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.h +++ b/assignment-client/src/avatars/AvatarMixerSlave.h @@ -26,6 +26,7 @@ public: int numIdentityPackets { 0 }; int numOthersIncluded { 0 }; int randomDrops { 0 }; + int overBudgetAvatars { 0 }; quint64 ignoreCalculationElapsedTime { 0 }; quint64 avatarDataPackingElapsedTime { 0 }; @@ -46,6 +47,7 @@ public: numIdentityPackets = 0; numOthersIncluded = 0; randomDrops = 0; + overBudgetAvatars = 0; ignoreCalculationElapsedTime = 0; avatarDataPackingElapsedTime = 0; @@ -65,6 +67,7 @@ public: numIdentityPackets += rhs.numIdentityPackets; numOthersIncluded += rhs.numOthersIncluded; randomDrops += rhs.randomDrops; + overBudgetAvatars += rhs.overBudgetAvatars; ignoreCalculationElapsedTime += rhs.ignoreCalculationElapsedTime; avatarDataPackingElapsedTime += rhs.avatarDataPackingElapsedTime;