From d44b50ee462978b4899c0b142f6ecbfb553f06b6 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 15 Oct 2009 15:25:02 -0700 Subject: * Removed some of the redundant broadcast functions in Scene and SceneGraph so it is clear who/what the broadcast is going to each time * Removed two redundant parameters from SceneObjectPart * Changed some code in terse update sending that was meant to work with references to work with value types (since Vector3 and Quaternion are structs) * Committing a preview of a new method for sending object updates efficiently (all commented out for now) --- OpenSim/Region/Framework/Scenes/Scene.cs | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d3d397d..d13d4fb 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1194,15 +1194,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Perform delegate action on all clients subscribing to updates from this region. - /// - /// - public void Broadcast(Action whatToDo) - { - ForEachScenePresence(delegate(ScenePresence presence) { whatToDo(presence.ControllingClient); }); - } - - /// /// Backup the scene. This acts as the main method of the backup thread. /// /// @@ -3048,17 +3039,13 @@ namespace OpenSim.Region.Framework.Scenes } m_eventManager.TriggerOnRemovePresence(agentID); - Broadcast(delegate(IClientAPI client) - { - try - { - client.SendKillObject(avatar.RegionHandle, avatar.LocalId); - } - catch (NullReferenceException) - { - //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway. - } - }); + ForEachClient( + delegate(IClientAPI client) + { + //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway + try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } + catch (NullReferenceException) { } + }); ForEachScenePresence( delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); @@ -3143,7 +3130,7 @@ namespace OpenSim.Region.Framework.Scenes return; } } - Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); + ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); } #endregion @@ -4211,7 +4198,7 @@ namespace OpenSim.Region.Framework.Scenes public void ForEachClient(Action action) { - m_sceneGraph.ForEachClient(action); + ClientManager.ForEach(action); } public void ForEachSOG(Action action) -- cgit v1.1 From 4b75353cbf50de3cae4c48ec90b55f30c1612c92 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 15 Oct 2009 16:35:27 -0700 Subject: Object update prioritization by Jim Greensky of Intel Labs, part one. This implements a simple distance prioritizer based on initial agent positions. Re-prioritizing and more advanced priority algorithms will follow soon --- OpenSim/Region/Framework/Scenes/Scene.cs | 40 +++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d13d4fb..c7efc19 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -57,6 +57,12 @@ namespace OpenSim.Region.Framework.Scenes public partial class Scene : SceneBase { + public enum UpdatePrioritizationSchemes { + Time = 0, + Distance = 1, + SimpleAngularDistance = 2, + } + public delegate void SynchronizeSceneHandler(Scene scene); public SynchronizeSceneHandler SynchronizeScene = null; @@ -268,9 +274,10 @@ namespace OpenSim.Region.Framework.Scenes private volatile bool shuttingdown = false; private int m_lastUpdate = Environment.TickCount; - private int m_maxPrimsPerFrame = 200; private bool m_firstHeartbeat = true; + private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; + private object m_deleting_scene_object = new object(); // the minimum time that must elapse before a changed object will be considered for persisted @@ -282,6 +289,8 @@ namespace OpenSim.Region.Framework.Scenes #region Properties + public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } + public AgentCircuitManager AuthenticateHandler { get { return m_authenticateHandler; } @@ -326,12 +335,6 @@ namespace OpenSim.Region.Framework.Scenes get { return m_sceneGraph.m_syncRoot; } } - public int MaxPrimsPerFrame - { - get { return m_maxPrimsPerFrame; } - set { m_maxPrimsPerFrame = value; } - } - /// /// This is for llGetRegionFPS /// @@ -509,7 +512,6 @@ namespace OpenSim.Region.Framework.Scenes m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); - m_maxPrimsPerFrame = startupConfig.GetInt("MaxPrimsPerFrame", 200); IConfig packetConfig = m_config.Configs["PacketPool"]; if (packetConfig != null) { @@ -518,6 +520,28 @@ namespace OpenSim.Region.Framework.Scenes } m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); + + IConfig interest_management_config = m_config.Configs["InterestManagement"]; + if (interest_management_config != null) + { + string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); + switch (update_prioritization_scheme) + { + case "time": + m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; + break; + case "distance": + m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance; + break; + case "simpleangulardistance": + m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance; + break; + default: + m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time"); + m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; + break; + } + } } catch { -- cgit v1.1 From 5a4fda9dc3aca873bcf034877eed1f9c5914493f Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 16 Oct 2009 11:09:18 -0700 Subject: Updating OpenSim.ini.example with the section required to enable a useful prioritization scheme --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c7efc19..0d8c241 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -542,6 +542,8 @@ namespace OpenSim.Region.Framework.Scenes break; } } + + m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); } catch { -- cgit v1.1 From fdb2a75ad357668b860fc5055e0630ef75a3ad20 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Sat, 17 Oct 2009 18:01:22 -0700 Subject: Committing the second part of Jim Greensky @ Intel Lab's patch, re-prioritizing updates --- OpenSim/Region/Framework/Scenes/Scene.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 49c1ebf..30fe976 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -278,6 +278,10 @@ namespace OpenSim.Region.Framework.Scenes private bool m_firstHeartbeat = true; private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; + private bool m_reprioritization_enabled = true; + private double m_reprioritization_interval = 2000.0; + private double m_root_reprioritization_distance = 5.0; + private double m_child_reprioritization_distance = 10.0; private object m_deleting_scene_object = new object(); @@ -291,6 +295,10 @@ namespace OpenSim.Region.Framework.Scenes #region Properties public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } + public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } } + public double ReprioritizationInterval { get { return m_reprioritization_interval; } } + public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } } + public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } } public AgentCircuitManager AuthenticateHandler { @@ -542,6 +550,11 @@ namespace OpenSim.Region.Framework.Scenes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; break; } + + m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true); + m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0); + m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0); + m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0); } m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); -- cgit v1.1 From 233e16b99cc80190d41143ecdfe01308eb39932a Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Sun, 18 Oct 2009 20:24:20 -0700 Subject: * Rewrote the methods that build ObjectUpdate and ImprovedTerseObjectUpdate packets to fill in the data more accurately and avoid allocating memory that is immediately thrown away * Changed the Send*Data structs in IClientAPI to use public readonly members instead of private members and getters * Made Parallel.ProcessorCount public * Started switching over packet building methods in LLClientView to use Util.StringToBytes[256/1024]() instead of Utils.StringToBytes() * More cleanup of the ScenePresences vs. ClientManager nightmare * ScenePresence.HandleAgentUpdate() will now time out and drop incoming AgentUpdate packets after three seconds. This fixes a deadlock on m_AgentUpdates that was blocking up the LLUDP server --- OpenSim/Region/Framework/Scenes/Scene.cs | 35 ++++++++++---------------------- 1 file changed, 11 insertions(+), 24 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 30fe976..70b11c3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -357,13 +357,6 @@ namespace OpenSim.Region.Framework.Scenes get { return m_defaultScriptEngine; } } - // Reference to all of the agents in the scene (root and child) - protected Dictionary m_scenePresences - { - get { return m_sceneGraph.ScenePresences; } - set { m_sceneGraph.ScenePresences = value; } - } - public EntityManager Entities { get { return m_sceneGraph.Entities; } @@ -1183,14 +1176,13 @@ namespace OpenSim.Region.Framework.Scenes /// Stats on the Simulator's performance private void SendSimStatsPackets(SimStats stats) { - List StatSendAgents = GetScenePresences(); - foreach (ScenePresence agent in StatSendAgents) - { - if (!agent.IsChildAgent) + ForEachScenePresence( + delegate(ScenePresence agent) { - agent.ControllingClient.SendSimStats(stats); + if (!agent.IsChildAgent) + agent.ControllingClient.SendSimStats(stats); } - } + ); } /// @@ -3501,10 +3493,8 @@ namespace OpenSim.Region.Framework.Scenes { ScenePresence presence; - lock (m_scenePresences) - { - m_scenePresences.TryGetValue(agentID, out presence); - } + lock (m_sceneGraph.ScenePresences) + m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence); if (presence != null) { @@ -3714,12 +3704,9 @@ namespace OpenSim.Region.Framework.Scenes public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { - ScenePresence sp = null; - lock (m_scenePresences) - { - if (m_scenePresences.ContainsKey(remoteClient.AgentId)) - sp = m_scenePresences[remoteClient.AgentId]; - } + ScenePresence sp; + lock (m_sceneGraph.ScenePresences) + m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp); if (sp != null) { @@ -4168,7 +4155,7 @@ namespace OpenSim.Region.Framework.Scenes public void ForEachScenePresence(Action action) { // We don't want to try to send messages if there are no avatars. - if (m_scenePresences != null) + if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null) { try { -- cgit v1.1 From 142008121e2e9c5ca5fca5de07b8a14e37279800 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Mon, 19 Oct 2009 15:19:09 -0700 Subject: * Change Util.FireAndForget to use ThreadPool.UnsafeQueueUserWorkItem(). This avoids .NET remoting and a managed->unmanaged->managed jump. Overall, a night and day performance difference * Initialize the LLClientView prim full update queue to the number of prims in the scene for a big performance boost * Reordered some comparisons on hot code paths for a minor speed boost * Removed an unnecessary call to the expensive DateTime.Now function (if you *have* to get the current time as opposed to Environment.TickCount, always use DateTime.UtcNow) * Don't fire the queue empty callback for the Resend category * Run the outgoing packet handler thread loop for each client synchronously. It seems like more time was being spent doing the execution asynchronously, and it made deadlocks very difficult to track down * Rewrote some expensive math in LandObject.cs * Optimized EntityManager to only lock on operations that need locking, and use TryGetValue() where possible * Only update the attachment database when an object is attached or detached * Other small misc. performance improvements --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 70b11c3..4f3cc98 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -228,6 +228,10 @@ namespace OpenSim.Region.Framework.Scenes protected IXMLRPC m_xmlrpcModule; protected IWorldComm m_worldCommModule; protected IAvatarFactory m_AvatarFactory; + public IAvatarFactory AvatarFactory + { + get { return m_AvatarFactory; } + } protected IConfigSource m_config; protected IRegionSerialiserModule m_serialiser; protected IInterregionCommsOut m_interregionCommsOut; -- cgit v1.1