Merge branch 'cpu-performance' of ssh://opensimulator.org/var/git/opensim into cpu-performance

cpu-performance
Diva Canto 2013-07-22 18:47:10 -07:00
commit be4034fd1c
3 changed files with 144 additions and 43 deletions

View File

@ -359,12 +359,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// cannot retain a reference to it outside of that method.
/// </remarks>
private AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
private float qdelta1;
private float qdelta2;
private float vdelta1;
private float vdelta2;
private float vdelta3;
private float vdelta4;
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@ -5576,7 +5570,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Scene/Avatar
// Threshold for body rotation to be a significant agent update
private const float QDELTA = 0.000001f;
// Threshold for camera rotation to be a significant agent update
private const float VDELTA = 0.01f;
/// <summary>
@ -5587,14 +5583,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name='x'></param>
public bool CheckAgentUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
{
// Compute these only once, when this function is called from down below
qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2);
//qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2);
vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
return CheckAgentMovementUpdateSignificance(x) || CheckAgentCameraUpdateSignificance(x);
}
@ -5606,24 +5594,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name='x'></param>
private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
{
if (
(qdelta1 > QDELTA) ||
float qdelta1 = 1 - (float)Math.Pow(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation), 2);
//qdelta2 = 1 - (float)Math.Pow(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation), 2);
bool movementSignificant =
(qdelta1 > QDELTA) // significant if body rotation above threshold
// Ignoring head rotation altogether, because it's not being used for anything interesting up the stack
//(qdelta2 > QDELTA * 10) ||
(x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) ||
(x.Far != m_thisAgentUpdateArgs.Far) ||
(x.Flags != m_thisAgentUpdateArgs.Flags) ||
(x.State != m_thisAgentUpdateArgs.State)
)
{
// || (qdelta2 > QDELTA * 10) // significant if head rotation above threshold
|| (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed
|| (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands
|| (x.Far != m_thisAgentUpdateArgs.Far) // significant if far distance changed
|| (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed
|| (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed
;
//if (movementSignificant)
//{
//m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}",
// qdelta1, qdelta2);
//m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3} (Thread {4})",
// x.ControlFlags, x.Flags, x.Far, x.State, Thread.CurrentThread.Name);
return true;
}
return false;
//m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}",
// x.ControlFlags, x.Flags, x.Far, x.State);
//}
return movementSignificant;
}
/// <summary>
@ -5634,23 +5625,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name='x'></param>
private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
{
if (
/* These 4 are the worst offenders!
* With Singularity, there is a bug where sometimes the spam on these doesn't stop */
float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
bool cameraSignificant =
(vdelta1 > VDELTA) ||
(vdelta2 > VDELTA) ||
(vdelta3 > VDELTA) ||
(vdelta4 > VDELTA)
)
{
;
//if (cameraSignificant)
//{
//m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}",
// x.CameraAtAxis, x.CameraCenter);
//m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}",
// x.CameraLeftAxis, x.CameraUpAxis);
return true;
}
//}
return false;
return cameraSignificant;
}
private bool HandleAgentUpdate(IClientAPI sener, Packet packet)

View File

@ -67,11 +67,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
m_udpServer.AddScene(scene);
StatsManager.RegisterStat(
new Stat(
"IncomingUDPReceivesCount",
"Number of UDP receives performed",
"Number of UDP receives performed",
"",
"clientstack",
scene.Name,
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = m_udpServer.UdpReceives,
StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"IncomingPacketsProcessedCount",
"Number of inbound UDP packets processed",
"Number of inbound UDP packets processed",
"Number of inbound LL protocol packets processed",
"Number of inbound LL protocol packets processed",
"",
"clientstack",
scene.Name,
@ -79,6 +92,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = m_udpServer.IncomingPacketsProcessed,
StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"OutgoingUDPSendsCount",
"Number of UDP sends performed",
"Number of UDP sends performed",
"",
"clientstack",
scene.Name,
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = m_udpServer.UdpSends,
StatVerbosity.Debug));
StatsManager.RegisterStat(
new Stat(
"AverageUDPProcessTime",
"Average number of milliseconds taken to process each incoming UDP packet in a sample.",
"This is for initial receive processing which is separate from the later client LL packet processing stage.",
"ms",
"clientstack",
scene.Name,
StatType.Pull,
MeasuresOfInterest.None,
stat => stat.Value = m_udpServer.AverageReceiveTicksForLastSamplePeriod / TimeSpan.TicksPerMillisecond,
// stat =>
// stat.Value = Math.Round(m_udpServer.AverageReceiveTicksForLastSamplePeriod / TimeSpan.TicksPerMillisecond, 7),
StatVerbosity.Debug));
}
public bool HandlesRegion(Location x)
@ -459,6 +500,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle);
StatsManager.RegisterStat(
new Stat(
"InboxPacketsCount",
"Number of LL protocol packets waiting for the second stage of processing after initial receive.",
"Number of LL protocol packets waiting for the second stage of processing after initial receive.",
"",
"clientstack",
scene.Name,
StatType.Pull,
MeasuresOfInterest.AverageChangeOverTime,
stat => stat.Value = packetInbox.Count,
StatVerbosity.Debug));
// XXX: These stats are also pool stats but we register them separately since they are currently not
// turned on and off by EnablePools()/DisablePools()
StatsManager.RegisterStat(
@ -828,7 +882,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
PacketPool.Instance.ReturnPacket(packet);
m_dataPresentEvent.Set();
}
private AutoResetEvent m_dataPresentEvent = new AutoResetEvent(false);
@ -1331,9 +1384,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
LLClientView llClient = client as LLClientView;
if (agentUpdate.AgentData.SessionID != client.SessionId
|| agentUpdate.AgentData.AgentID != client.AgentId
|| !((LLClientView)client).CheckAgentUpdateSignificance(agentUpdate.AgentData))
|| !(llClient == null || llClient.CheckAgentUpdateSignificance(agentUpdate.AgentData)) )
{
PacketPool.Instance.ReturnPacket(packet);
return;

View File

@ -77,6 +77,36 @@ namespace OpenMetaverse
/// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks>
public bool IsRunningOutbound { get; private set; }
/// <summary>
/// Number of UDP receives.
/// </summary>
public int UdpReceives { get; private set; }
/// <summary>
/// Number of UDP sends
/// </summary>
public int UdpSends { get; private set; }
/// <summary>
/// Number of receives over which to establish a receive time average.
/// </summary>
private readonly static int s_receiveTimeSamples = 500;
/// <summary>
/// Current number of samples taken to establish a receive time average.
/// </summary>
private int m_currentReceiveTimeSamples;
/// <summary>
/// Cumulative receive time for the sample so far.
/// </summary>
private int m_receiveTicksInCurrentSamplePeriod;
/// <summary>
/// The average time taken for each require receive in the last sample.
/// </summary>
public float AverageReceiveTicksForLastSamplePeriod { get; private set; }
/// <summary>
/// Default constructor
/// </summary>
@ -275,6 +305,8 @@ namespace OpenMetaverse
// to AsyncBeginReceive
if (IsRunningInbound)
{
UdpReceives++;
// Asynchronous mode will start another receive before the
// callback for this packet is even fired. Very parallel :-)
if (m_asyncPacketHandling)
@ -286,6 +318,8 @@ namespace OpenMetaverse
try
{
int startTick = Util.EnvironmentTickCount();
// get the length of data actually read from the socket, store it with the
// buffer
buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint);
@ -293,6 +327,23 @@ namespace OpenMetaverse
// call the abstract method PacketReceived(), passing the buffer that
// has just been filled from the socket read.
PacketReceived(buffer);
// If more than one thread can be calling AsyncEndReceive() at once (e.g. if m_asyncPacketHandler)
// then a particular stat may be inaccurate due to a race condition. We won't worry about this
// since this should be rare and won't cause a runtime problem.
if (m_currentReceiveTimeSamples >= s_receiveTimeSamples)
{
AverageReceiveTicksForLastSamplePeriod
= (float)m_receiveTicksInCurrentSamplePeriod / s_receiveTimeSamples;
m_receiveTicksInCurrentSamplePeriod = 0;
m_currentReceiveTimeSamples = 0;
}
else
{
m_receiveTicksInCurrentSamplePeriod += Util.EnvironmentTickCountSubtract(startTick);
m_currentReceiveTimeSamples++;
}
}
catch (SocketException) { }
catch (ObjectDisposedException) { }
@ -306,7 +357,6 @@ namespace OpenMetaverse
if (!m_asyncPacketHandling)
AsyncBeginReceive();
}
}
}
@ -336,6 +386,8 @@ namespace OpenMetaverse
{
// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
m_udpSocket.EndSendTo(result);
UdpSends++;
}
catch (SocketException) { }
catch (ObjectDisposedException) { }