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
protected int m_fps = 10;
protected int m_frame;
protected uint m_frame;
protected float m_timespan = 0.089f;
protected DateTime m_lastupdate = DateTime.UtcNow;
@ -1018,36 +1018,24 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public override void Update()
{
int maintc = 0;
float physicsFPS;
int maintc;
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;
float physicsFPS = 0;
physicsFPS = 0f;
frameMS = Environment.TickCount;
maintc = maintc = frameMS = otherMS = Environment.TickCount;
// Increment the frame counter
++m_frame;
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
CheckAtTargets();
// Update SceneObjectGroups that have scheduled themselves for updates
// Objects queue their updates onto all scene presences
if (m_frame % m_update_objects == 0)
@ -1067,13 +1055,13 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.UpdateScenePresenceMovement();
physicsMS = Environment.TickCount;
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(
Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
);
if (m_frame % m_update_physics == 0 && SynchronizeScene != null)
SynchronizeScene(this);
if (m_frame % m_update_physics == 0)
{
if (m_physics_enabled)
physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
if (SynchronizeScene != null)
SynchronizeScene(this);
}
physicsMS = Environment.TickCount - physicsMS;
physicsMS += physicsMS2;
@ -1095,25 +1083,27 @@ namespace OpenSim.Region.Framework.Scenes
if (m_frame % m_update_land == 0)
UpdateLand();
otherMS = Environment.TickCount - otherMS;
int tickCount = Environment.TickCount;
otherMS = tickCount - otherMS;
frameMS = tickCount - frameMS;
// if (m_frame%m_update_avatars == 0)
// UpdateInWorldTime();
StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1);
StatsReporter.AddInPackets(0);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
frameMS = Environment.TickCount - frameMS;
StatsReporter.addFrameMS(frameMS);
StatsReporter.addPhysicsMS(physicsMS);
StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
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,
// 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)
{
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>
protected internal void UpdateObjectGroups()
{
Dictionary<UUID, SceneObjectGroup> updates;
List<SceneObjectGroup> updates;
// Some updates add more updates to the updateList.
// Get the current list of updates and clear the list before iterating
lock (m_updateList)
{
updates = new Dictionary<UUID, SceneObjectGroup>(m_updateList);
updates = new List<SceneObjectGroup>(m_updateList.Values);
m_updateList.Clear();
}
// 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.
try
{
kvp.Value.Update();
sog.Update();
}
catch (Exception e)
{
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);
//if (IsAttachment)
//{
//foreach (SceneObjectPart part in m_parts.Values)
//{
//part.SendScheduledUpdates();
//}
//return;
//}
if (UsePhysics && Util.DistanceLessThan(lastPhysGroupPos, AbsolutePosition, 0.02))
if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f))
{
m_rootPart.UpdateFlag = 1;
lastPhysGroupPos = AbsolutePosition;
}
if (UsePhysics && ((Math.Abs(lastPhysGroupRot.W - GroupRotation.W) > 0.1)
|| (Math.Abs(lastPhysGroupRot.X - GroupRotation.X) > 0.1)
|| (Math.Abs(lastPhysGroupRot.Y - GroupRotation.Y) > 0.1)
|| (Math.Abs(lastPhysGroupRot.Z - GroupRotation.Z) > 0.1)))
if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f))
{
m_rootPart.UpdateFlag = 1;
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 byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
public static byte[] DefaultTexture;
public static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
public UUID currentParcelUUID = UUID.Zero;
@ -100,9 +99,9 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_updateflag;
private byte m_movementflag;
private readonly List<NewForce> m_forcesList = new List<NewForce>();
private Vector3? m_forceToApply;
private uint m_requestedSitTargetID;
private UUID m_requestedSitTargetUUID = UUID.Zero;
private UUID m_requestedSitTargetUUID;
private SendCourseLocationsMethod m_sendCourseLocationsMethod;
private bool m_startAnimationSet;
@ -456,12 +455,9 @@ namespace OpenSim.Region.Framework.Scenes
{
get
{
if (m_physicsActor != null)
{
m_velocity.X = m_physicsActor.Velocity.X;
m_velocity.Y = m_physicsActor.Velocity.Y;
m_velocity.Z = m_physicsActor.Velocity.Z;
}
PhysicsActor actor = m_physicsActor;
if (actor != null)
m_velocity = m_physicsActor.Velocity;
return m_velocity;
}
@ -2278,7 +2274,7 @@ namespace OpenSim.Region.Framework.Scenes
{
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.
// 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);
regions.Remove(m_scene.RegionInfo.RegionHandle);
MakeRootAgent(new Vector3(127, 127, 127), true);
MakeRootAgent(new Vector3(127f, 127f, 127f), true);
// Async command
if (m_scene.SceneGridService != null)
@ -2299,28 +2295,24 @@ namespace OpenSim.Region.Framework.Scenes
System.Threading.Thread.Sleep(500);
}
if (m_scene.SceneGridService != null)
{
m_scene.SceneGridService.EnableNeighbourChildAgents(this, new List<RegionInfo>());
}
return;
}
m_perfMonMS = Environment.TickCount;
m_rotation = rotation;
NewForce newVelocity = new NewForce();
Vector3 direc = vec * rotation;
direc.Normalize();
direc *= 0.03f * 128f * m_speedModifier;
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 colliding = (m_physicsActor.IsColliding==true);
//if (controlland)
@ -2348,10 +2340,8 @@ namespace OpenSim.Region.Framework.Scenes
}
}
newVelocity.X = direc.X;
newVelocity.Y = direc.Y;
newVelocity.Z = direc.Z;
m_forcesList.Add(newVelocity);
// TODO: Add the force instead of only setting it to support multiple forces per frame?
m_forceToApply = direc;
m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
}
@ -3298,47 +3288,18 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public override void UpdateMovement()
{
lock (m_forcesList)
if (m_forceToApply.HasValue)
{
if (m_forcesList.Count > 0)
{
//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];
Vector3 force = m_forceToApply.Value;
m_updateflag = true;
try
{
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_updateflag = true;
movementvector = force;
Velocity = force;
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)
{
throw new Exception("Can't set Text on avatar.");
@ -3349,7 +3310,6 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void AddToPhysicalScene(bool isFlying)
{
PhysicsScene scene = m_scene.PhysicsScene;
Vector3 pVec = AbsolutePosition;
@ -3478,11 +3438,6 @@ namespace OpenSim.Region.Framework.Scenes
public ScenePresence()
{
if (DefaultTexture == null)
{
Primitive.TextureEntry textu = AvatarAppearance.GetDefaultTexture();
DefaultTexture = textu.GetBytes();
}
m_sendCourseLocationsMethod = SendCoarseLocationsDefault;
CreateSceneViewer();
}