From 4ca71fd96a9ca8578b65ef9f3a2dd8f235aa8ffe Mon Sep 17 00:00:00 2001 From: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> Date: Tue, 15 Feb 2022 11:02:39 -0600 Subject: [PATCH 1/2] Added MULTIPLAYER budget. Added profiler markers, visible in PIX. Signed-off-by: AMZN-Olex <5432499+AMZN-Olex@users.noreply.github.com> --- .../Source/MultiplayerSystemComponent.cpp | 12 ++++++++- .../EntityReplicationManager.cpp | 27 ++++++++++++++----- .../NetworkEntity/NetworkEntityManager.cpp | 4 +++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index dad584d3e8..ad0be24661 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -39,6 +39,9 @@ #include #include +#include + +AZ_DEFINE_BUDGET(MULTIPLAYER); namespace AZ::ConsoleTypeHelpers { @@ -347,6 +350,8 @@ namespace Multiplayer void MultiplayerSystemComponent::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) { + AZ_PROFILE_SCOPE(MULTIPLAYER, "MultiplayerTick"); + if (bg_multiplayerDebugDraw) { m_networkEntityManager.DebugDraw(); @@ -388,7 +393,9 @@ namespace Multiplayer stats.m_clientConnectionCount = 0; // Send out the game state update to all connections - { + { + AZ_PROFILE_SCOPE(MULTIPLAYER, "SendOutGameStateUpdateToAllConnections"); + auto sendNetworkUpdates = [&stats](IConnection& connection) { if (connection.GetUserData() != nullptr) @@ -434,6 +441,7 @@ namespace Multiplayer if (!packet.GetCommandSet().empty()) { + AZ_PROFILE_SCOPE(MULTIPLAYER, "SendReliablePackets"); m_networkInterface->GetConnectionSet().VisitConnections(visitor); } } @@ -1012,6 +1020,8 @@ namespace Multiplayer void MultiplayerSystemComponent::TickVisibleNetworkEntities(float deltaTime, float serverRateSeconds) { + AZ_PROFILE_SCOPE(MULTIPLAYER, "TickVisibleNetworkEntities"); + m_tickFactor += deltaTime / serverRateSeconds; // Linear close to the origin, but asymptote at y = 1 m_renderBlendFactor = AZStd::clamp(1.0f - (std::pow(cl_renderTickBlendBase, m_tickFactor)), 0.0f, m_tickFactor); diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp index 893799a296..a9f1a33e31 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp @@ -26,8 +26,11 @@ #include #include #include +#include #include +AZ_DECLARE_BUDGET(MULTIPLAYER); + namespace Multiplayer { // Current max size for a UdpPacketHeader is 11 bytes @@ -78,6 +81,8 @@ namespace Multiplayer void EntityReplicationManager::ActivatePendingEntities() { + AZ_PROFILE_SCOPE(MULTIPLAYER, "ActivatePendingEntities"); + AZStd::vector notReadyEntities; const AZ::TimeMs endTimeMs = AZ::GetElapsedTimeMs() + m_entityActivationTimeSliceMs; @@ -126,17 +131,23 @@ namespace Multiplayer GetRemoteHostId().GetString().c_str() ); - // Prep a replication record for send, at this point, everything needs to be sent - for (EntityReplicator* replicator : toSendList) { - replicator->GetPropertyPublisher()->PrepareSerialization(); + AZ_PROFILE_SCOPE(MULTIPLAYER, "PrepareSerialization"); + // Prep a replication record for send, at this point, everything needs to be sent + for (EntityReplicator* replicator : toSendList) + { + replicator->GetPropertyPublisher()->PrepareSerialization(); + } } - // While our to send list is not empty, build up another packet to send - do { - SendEntityUpdateMessages(toSendList); - } while (!toSendList.empty()); + AZ_PROFILE_SCOPE(MULTIPLAYER, "SendEntityUpdateMessages"); + // While our to send list is not empty, build up another packet to send + do + { + SendEntityUpdateMessages(toSendList); + } while (!toSendList.empty()); + } } SendEntityRpcs(m_deferredRpcMessagesReliable, true); @@ -163,6 +174,8 @@ namespace Multiplayer { return EntityReplicatorList(); } + + AZ_PROFILE_SCOPE(MULTIPLAYER, "GenerateEntityUpdateList"); // Generate a list of all our entities that need updates EntityReplicatorList toSendList; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp index 0a6aeea8a8..a3d1988e66 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp @@ -25,6 +25,8 @@ #include #include +AZ_DECLARE_BUDGET(MULTIPLAYER); + namespace Multiplayer { AZ_CVAR(bool, net_DebugCheckNetworkEntityManager, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Enables extra debug checks inside the NetworkEntityManager"); @@ -203,11 +205,13 @@ namespace Multiplayer void NetworkEntityManager::NotifyEntitiesDirtied() { + AZ_PROFILE_SCOPE(MULTIPLAYER, "NotifyEntitiesDirtied"); m_onEntityMarkedDirty.Signal(); } void NetworkEntityManager::NotifyEntitiesChanged() { + AZ_PROFILE_SCOPE(MULTIPLAYER, "NotifyEntitiesChanged"); m_onEntityNotifyChanges.Signal(); } From f94ec80d9feae4a7f3bdf22cf27c03f42771aa87 Mon Sep 17 00:00:00 2001 From: Olex Lozitskiy <5432499+AMZN-Olex@users.noreply.github.com> Date: Thu, 17 Feb 2022 19:49:31 -0500 Subject: [PATCH 2/2] Improved profile marker names Signed-off-by: Olex Lozitskiy <5432499+AMZN-Olex@users.noreply.github.com> --- .../Code/Source/MultiplayerSystemComponent.cpp | 8 ++++---- .../EntityReplication/EntityReplicationManager.cpp | 10 +++++----- .../Source/NetworkEntity/NetworkEntityManager.cpp | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index ad0be24661..71209726ff 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -350,7 +350,7 @@ namespace Multiplayer void MultiplayerSystemComponent::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) { - AZ_PROFILE_SCOPE(MULTIPLAYER, "MultiplayerTick"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "MultiplayerSystemComponent: OnTick"); if (bg_multiplayerDebugDraw) { @@ -394,7 +394,7 @@ namespace Multiplayer // Send out the game state update to all connections { - AZ_PROFILE_SCOPE(MULTIPLAYER, "SendOutGameStateUpdateToAllConnections"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "MultiplayerSystemComponent: OnTick - SendOutGameStateUpdate"); auto sendNetworkUpdates = [&stats](IConnection& connection) { @@ -441,7 +441,7 @@ namespace Multiplayer if (!packet.GetCommandSet().empty()) { - AZ_PROFILE_SCOPE(MULTIPLAYER, "SendReliablePackets"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "MultiplayerSystemComponent: OnTick - SendReliablePackets"); m_networkInterface->GetConnectionSet().VisitConnections(visitor); } } @@ -1020,7 +1020,7 @@ namespace Multiplayer void MultiplayerSystemComponent::TickVisibleNetworkEntities(float deltaTime, float serverRateSeconds) { - AZ_PROFILE_SCOPE(MULTIPLAYER, "TickVisibleNetworkEntities"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "MultiplayerSystemComponent: TickVisibleNetworkEntities"); m_tickFactor += deltaTime / serverRateSeconds; // Linear close to the origin, but asymptote at y = 1 diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp index a9f1a33e31..f04769a2de 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp @@ -81,7 +81,7 @@ namespace Multiplayer void EntityReplicationManager::ActivatePendingEntities() { - AZ_PROFILE_SCOPE(MULTIPLAYER, "ActivatePendingEntities"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "EntityReplicationManager: ActivatePendingEntities"); AZStd::vector notReadyEntities; @@ -132,7 +132,7 @@ namespace Multiplayer ); { - AZ_PROFILE_SCOPE(MULTIPLAYER, "PrepareSerialization"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "EntityReplicationManager: SendUpdates - PrepareSerialization"); // Prep a replication record for send, at this point, everything needs to be sent for (EntityReplicator* replicator : toSendList) { @@ -141,7 +141,7 @@ namespace Multiplayer } { - AZ_PROFILE_SCOPE(MULTIPLAYER, "SendEntityUpdateMessages"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "EntityReplicationManager: SendUpdates - SendEntityUpdateMessages"); // While our to send list is not empty, build up another packet to send do { @@ -174,8 +174,8 @@ namespace Multiplayer { return EntityReplicatorList(); } - - AZ_PROFILE_SCOPE(MULTIPLAYER, "GenerateEntityUpdateList"); + + AZ_PROFILE_SCOPE(MULTIPLAYER, "EntityReplicationManager: GenerateEntityUpdateList"); // Generate a list of all our entities that need updates EntityReplicatorList toSendList; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp index a3d1988e66..7f3636f388 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp @@ -205,13 +205,13 @@ namespace Multiplayer void NetworkEntityManager::NotifyEntitiesDirtied() { - AZ_PROFILE_SCOPE(MULTIPLAYER, "NotifyEntitiesDirtied"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "NetworkEntityManager: NotifyEntitiesDirtied"); m_onEntityMarkedDirty.Signal(); } void NetworkEntityManager::NotifyEntitiesChanged() { - AZ_PROFILE_SCOPE(MULTIPLAYER, "NotifyEntitiesChanged"); + AZ_PROFILE_SCOPE(MULTIPLAYER, "NetworkEntityManager: NotifyEntitiesChanged"); m_onEntityNotifyChanges.Signal(); } @@ -364,7 +364,7 @@ namespace Multiplayer m_networkEntityTracker.erase(entityId); } } - + INetworkEntityManager::EntityList NetworkEntityManager::CreateEntitiesImmediate( const AzFramework::Spawnable& spawnable, NetEntityRole netEntityRole, AutoActivate autoActivate) { @@ -461,12 +461,12 @@ namespace Multiplayer { return returnList; } - + auto spawnableAssetId = m_networkPrefabLibrary.GetAssetIdByName(prefabEntryId.m_prefabName); // Required for sync-instantiation. Todo: keep the reference in NetworkSpawnableLibrary auto netSpawnableAsset = AZ::Data::AssetManager::Instance().GetAsset(spawnableAssetId, AZ::Data::AssetLoadBehavior::PreLoad); AZ::Data::AssetManager::Instance().BlockUntilLoadComplete(netSpawnableAsset); - + AzFramework::Spawnable* netSpawnable = netSpawnableAsset.GetAs(); if (!netSpawnable) { @@ -623,7 +623,7 @@ namespace Multiplayer NetworkHierarchyRootComponentController* hierarchyRootController = entityHandle.FindController(); NetworkHierarchyChildComponentController* hierarchyChildController = entityHandle.FindController(); - AZStd::vector hierarchicalEntities; + AZStd::vector hierarchicalEntities; // Get the entities in this hierarchy if (hierarchyRootController)