Small performance tweaks to code called by the heartbeat loop

0.6.8-post-fixes
John Hurliman 2009-10-28 23:10:16 -07:00
parent 1c9696a9d2
commit 59eb378d16
4 changed files with 53 additions and 117 deletions

View File

@ -257,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes
// Central Update Loop // Central Update Loop
protected int m_fps = 10; protected int m_fps = 10;
protected int m_frame; protected uint m_frame;
protected float m_timespan = 0.089f; protected float m_timespan = 0.089f;
protected DateTime m_lastupdate = DateTime.UtcNow; protected DateTime m_lastupdate = DateTime.UtcNow;
@ -1018,33 +1018,21 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public override void Update() public override void Update()
{ {
int maintc = 0; float physicsFPS;
int maintc;
while (!shuttingdown) while (!shuttingdown)
{ {
//#if DEBUG
// int w = 0, io = 0;
// ThreadPool.GetAvailableThreads(out w, out io);
// if ((w < 10) || (io < 10))
// m_log.DebugFormat("[WARNING]: ThreadPool reaching exhaustion. workers = {0}; io = {1}", w, io);
//#endif
maintc = Environment.TickCount;
TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
float physicsFPS = 0; physicsFPS = 0f;
frameMS = Environment.TickCount; maintc = maintc = frameMS = otherMS = Environment.TickCount;
// Increment the frame counter
++m_frame;
try try
{ {
// Increment the frame counter
m_frame++;
// Loop it
if (m_frame == Int32.MaxValue)
m_frame = 0;
otherMS = Environment.TickCount;
// Check if any objects have reached their targets // Check if any objects have reached their targets
CheckAtTargets(); CheckAtTargets();
@ -1067,13 +1055,13 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.UpdateScenePresenceMovement(); m_sceneGraph.UpdateScenePresenceMovement();
physicsMS = Environment.TickCount; physicsMS = Environment.TickCount;
if ((m_frame % m_update_physics == 0) && m_physics_enabled) if (m_frame % m_update_physics == 0)
physicsFPS = m_sceneGraph.UpdatePhysics( {
Math.Max(SinceLastFrame.TotalSeconds, m_timespan) if (m_physics_enabled)
); physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
if (m_frame % m_update_physics == 0 && SynchronizeScene != null) if (SynchronizeScene != null)
SynchronizeScene(this); SynchronizeScene(this);
}
physicsMS = Environment.TickCount - physicsMS; physicsMS = Environment.TickCount - physicsMS;
physicsMS += physicsMS2; physicsMS += physicsMS2;
@ -1095,25 +1083,27 @@ namespace OpenSim.Region.Framework.Scenes
if (m_frame % m_update_land == 0) if (m_frame % m_update_land == 0)
UpdateLand(); UpdateLand();
otherMS = Environment.TickCount - otherMS; int tickCount = Environment.TickCount;
otherMS = tickCount - otherMS;
frameMS = tickCount - frameMS;
// if (m_frame%m_update_avatars == 0) // if (m_frame%m_update_avatars == 0)
// UpdateInWorldTime(); // UpdateInWorldTime();
StatsReporter.AddPhysicsFPS(physicsFPS); StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation); StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1); StatsReporter.AddFPS(1);
StatsReporter.AddInPackets(0);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
frameMS = Environment.TickCount - frameMS;
StatsReporter.addFrameMS(frameMS); StatsReporter.addFrameMS(frameMS);
StatsReporter.addPhysicsMS(physicsMS); StatsReporter.addPhysicsMS(physicsMS);
StatsReporter.addOtherMS(otherMS); StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
} }
if (loginsdisabled && (m_frame > 20))
if (loginsdisabled && m_frame > 20)
{ {
// In 99.9% of cases it is a bad idea to manually force garbage collection. However, // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
// this is a rare case where we know we have just went through a long cycle of heap // this is a rare case where we know we have just went through a long cycle of heap
@ -1176,9 +1166,9 @@ namespace OpenSim.Region.Framework.Scenes
{ {
lock (m_groupsWithTargets) lock (m_groupsWithTargets)
{ {
foreach (KeyValuePair<UUID, SceneObjectGroup> kvp in m_groupsWithTargets) foreach (SceneObjectGroup entry in m_groupsWithTargets.Values)
{ {
kvp.Value.checkAtTargets(); entry.checkAtTargets();
} }
} }
} }

View File

@ -369,26 +369,30 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
protected internal void UpdateObjectGroups() protected internal void UpdateObjectGroups()
{ {
Dictionary<UUID, SceneObjectGroup> updates; List<SceneObjectGroup> updates;
// Some updates add more updates to the updateList. // Some updates add more updates to the updateList.
// Get the current list of updates and clear the list before iterating // Get the current list of updates and clear the list before iterating
lock (m_updateList) lock (m_updateList)
{ {
updates = new Dictionary<UUID, SceneObjectGroup>(m_updateList); updates = new List<SceneObjectGroup>(m_updateList.Values);
m_updateList.Clear(); m_updateList.Clear();
} }
// Go through all updates // Go through all updates
foreach (KeyValuePair<UUID, SceneObjectGroup> kvp in updates) for (int i = 0; i < updates.Count; i++)
{ {
SceneObjectGroup sog = updates[i];
// Don't abort the whole update if one entity happens to give us an exception. // Don't abort the whole update if one entity happens to give us an exception.
try try
{ {
kvp.Value.Update(); sog.Update();
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[INNER SCENE]: Failed to update {0}, {1} - {2}", kvp.Value.Name, kvp.Value.UUID, e); "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
} }
} }
} }

View File

@ -1857,28 +1857,15 @@ namespace OpenSim.Region.Framework.Scenes
{ {
bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
//if (IsAttachment) if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f))
//{
//foreach (SceneObjectPart part in m_parts.Values)
//{
//part.SendScheduledUpdates();
//}
//return;
//}
if (UsePhysics && Util.DistanceLessThan(lastPhysGroupPos, AbsolutePosition, 0.02))
{ {
m_rootPart.UpdateFlag = 1; m_rootPart.UpdateFlag = 1;
lastPhysGroupPos = AbsolutePosition; lastPhysGroupPos = AbsolutePosition;
} }
if (UsePhysics && ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1) if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f))
|| (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
|| (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
|| (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1)))
{ {
m_rootPart.UpdateFlag = 1; m_rootPart.UpdateFlag = 1;
lastPhysGroupRot = GroupRotation; lastPhysGroupRot = GroupRotation;
} }

View File

@ -76,8 +76,7 @@ namespace OpenSim.Region.Framework.Scenes
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
public static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
public static byte[] DefaultTexture;
public UUID currentParcelUUID = UUID.Zero; public UUID currentParcelUUID = UUID.Zero;
@ -100,9 +99,9 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_updateflag; private bool m_updateflag;
private byte m_movementflag; private byte m_movementflag;
private readonly List<NewForce> m_forcesList = new List<NewForce>(); private Vector3? m_forceToApply;
private uint m_requestedSitTargetID; private uint m_requestedSitTargetID;
private UUID m_requestedSitTargetUUID = UUID.Zero; private UUID m_requestedSitTargetUUID;
private SendCourseLocationsMethod m_sendCourseLocationsMethod; private SendCourseLocationsMethod m_sendCourseLocationsMethod;
private bool m_startAnimationSet; private bool m_startAnimationSet;
@ -456,12 +455,9 @@ namespace OpenSim.Region.Framework.Scenes
{ {
get get
{ {
if (m_physicsActor != null) PhysicsActor actor = m_physicsActor;
{ if (actor != null)
m_velocity.X = m_physicsActor.Velocity.X; m_velocity = m_physicsActor.Velocity;
m_velocity.Y = m_physicsActor.Velocity.Y;
m_velocity.Z = m_physicsActor.Velocity.Z;
}
return m_velocity; return m_velocity;
} }
@ -2278,7 +2274,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (m_isChildAgent) if (m_isChildAgent)
{ {
m_log.Debug("DEBUG: AddNewMovement: child agent, Making root agent!"); m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!");
// we have to reset the user's child agent connections. // we have to reset the user's child agent connections.
// Likely, here they've lost the eventqueue for other regions so border // Likely, here they've lost the eventqueue for other regions so border
@ -2287,7 +2283,7 @@ namespace OpenSim.Region.Framework.Scenes
List<ulong> regions = new List<ulong>(KnownChildRegionHandles); List<ulong> regions = new List<ulong>(KnownChildRegionHandles);
regions.Remove(m_scene.RegionInfo.RegionHandle); regions.Remove(m_scene.RegionInfo.RegionHandle);
MakeRootAgent(new Vector3(127, 127, 127), true); MakeRootAgent(new Vector3(127f, 127f, 127f), true);
// Async command // Async command
if (m_scene.SceneGridService != null) if (m_scene.SceneGridService != null)
@ -2299,28 +2295,24 @@ namespace OpenSim.Region.Framework.Scenes
System.Threading.Thread.Sleep(500); System.Threading.Thread.Sleep(500);
} }
if (m_scene.SceneGridService != null) if (m_scene.SceneGridService != null)
{ {
m_scene.SceneGridService.EnableNeighbourChildAgents(this, new List<RegionInfo>()); m_scene.SceneGridService.EnableNeighbourChildAgents(this, new List<RegionInfo>());
} }
return; return;
} }
m_perfMonMS = Environment.TickCount; m_perfMonMS = Environment.TickCount;
m_rotation = rotation; m_rotation = rotation;
NewForce newVelocity = new NewForce();
Vector3 direc = vec * rotation; Vector3 direc = vec * rotation;
direc.Normalize(); direc.Normalize();
direc *= 0.03f * 128f * m_speedModifier; direc *= 0.03f * 128f * m_speedModifier;
if (m_physicsActor.Flying) if (m_physicsActor.Flying)
{ {
direc *= 4; direc *= 4.0f;
//bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
//bool colliding = (m_physicsActor.IsColliding==true); //bool colliding = (m_physicsActor.IsColliding==true);
//if (controlland) //if (controlland)
@ -2348,10 +2340,8 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
newVelocity.X = direc.X; // TODO: Add the force instead of only setting it to support multiple forces per frame?
newVelocity.Y = direc.Y; m_forceToApply = direc;
newVelocity.Z = direc.Z;
m_forcesList.Add(newVelocity);
m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
} }
@ -3298,46 +3288,17 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public override void UpdateMovement() public override void UpdateMovement()
{ {
lock (m_forcesList) if (m_forceToApply.HasValue)
{ {
if (m_forcesList.Count > 0) Vector3 force = m_forceToApply.Value;
{
//we are only interested in the last velocity added to the list [Although they are called forces, they are actually velocities]
NewForce force = m_forcesList[m_forcesList.Count - 1];
m_updateflag = true; m_updateflag = true;
try movementvector = force;
{ Velocity = force;
movementvector.X = force.X;
movementvector.Y = force.Y;
movementvector.Z = force.Z;
Velocity = movementvector;
}
catch (NullReferenceException)
{
// Under extreme load, this returns a NullReference Exception that we can ignore.
// Ignoring this causes no movement to be sent to the physics engine...
// which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter!
}
m_forcesList.Clear(); m_forceToApply = null;
} }
} }
}
static ScenePresence()
{
Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture();
DefaultTexture = textu.GetBytes();
}
public class NewForce
{
public float X;
public float Y;
public float Z;
}
public override void SetText(string text, Vector3 color, double alpha) public override void SetText(string text, Vector3 color, double alpha)
{ {
@ -3349,7 +3310,6 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void AddToPhysicalScene(bool isFlying) public void AddToPhysicalScene(bool isFlying)
{ {
PhysicsScene scene = m_scene.PhysicsScene; PhysicsScene scene = m_scene.PhysicsScene;
Vector3 pVec = AbsolutePosition; Vector3 pVec = AbsolutePosition;
@ -3478,11 +3438,6 @@ namespace OpenSim.Region.Framework.Scenes
public ScenePresence() public ScenePresence()
{ {
if (DefaultTexture == null)
{
Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture();
DefaultTexture = textu.GetBytes();
}
m_sendCourseLocationsMethod = SendCoarseLocationsDefault; m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
CreateSceneViewer(); CreateSceneViewer();
} }