浏览代码

[timer] Add gauges to csharp timers to reflect python gauges. (#3013)

/develop/tanhsquash
GitHub 4 年前
当前提交
4efcb327
共有 3 个文件被更改,包括 74 次插入6 次删除
  1. 9
      UnitySDK/Assets/ML-Agents/Editor/Tests/TimerTest.cs
  2. 70
      UnitySDK/Assets/ML-Agents/Scripts/Timer.cs
  3. 1
      UnitySDK/UnitySDK.sln.DotSettings

9
UnitySDK/Assets/ML-Agents/Editor/Tests/TimerTest.cs


using NUnit.Framework;
using UnityEditor.Graphs;
using UnityEngine;
namespace MLAgents.Tests

{
TimerStack myTimer = TimerStack.Instance;
myTimer.Reset();
using (myTimer.Scoped("foo"))
{
for (int i = 0; i < 5; i++)

myTimer.SetGauge("my_gauge", (float)i);
}
}
}

Assert.AreEqual(rootChildren["foo"].NumCalls, 1);
var gauge = myTimer.RootNode.Gauges["my_gauge"];
Assert.NotNull(gauge);
Assert.AreEqual(5, gauge.count);
Assert.AreEqual(0, gauge.minValue);
Assert.AreEqual(4, gauge.maxValue);
Assert.AreEqual(4, gauge.value);
var fooChildren = rootChildren["foo"].Children;
Assert.That(fooChildren, Contains.Key("bar"));

70
UnitySDK/Assets/ML-Agents/Scripts/Timer.cs


// Compile with: csc CRefTest.cs -doc:Results.xml
using System;
using UnityEngine;
using System.Collections.Generic;
using System.IO;

/// </summary>
[DataMember(Name = "children", Order = 999)]
Dictionary<string, TimerNode> m_Children;
/// <summary>
/// Gauge Nodes to measure arbitrary values.
/// </summary>
[DataMember(Name = "gauges", EmitDefaultValue = false)]
Dictionary<string, GaugeNode> m_Gauges;
/// <summary>
/// Custom sampler used to add timings to the profiler.

var currentTicks = m_TotalTicks;
if (m_TickStart != 0)
{
currentTicks += (System.DateTime.Now.Ticks - m_TickStart);
currentTicks += (DateTime.Now.Ticks - m_TickStart);
}
return currentTicks;

set {} // Serialization needs this, but unused.
}
public Dictionary<string, GaugeNode> Gauges
{
get { return m_Gauges; }
}
/// <summary>
/// Total seconds spent in this block, excluding it's children.
/// </summary>

// have a sensible value for total time (the running time since reset).
// The root node doesn't have a sampler since that could interfere with the profiler.
m_NumCalls = 1;
m_TickStart = System.DateTime.Now.Ticks;
m_TickStart = DateTime.Now.Ticks;
m_Gauges = new Dictionary<string, GaugeNode>();
}
else
{

public void Begin()
{
m_Sampler?.Begin();
m_TickStart = System.DateTime.Now.Ticks;
m_TickStart = DateTime.Now.Ticks;
}
/// <summary>

{
var elapsed = System.DateTime.Now.Ticks - m_TickStart;
var elapsed = DateTime.Now.Ticks - m_TickStart;
m_TotalTicks += elapsed;
m_TickStart = 0;
m_NumCalls++;

}
/// <summary>
/// Tracks the most recent value of a metric. This is analogous to gauges in statsd.
/// </summary>
[DataContract]
public class GaugeNode
{
[DataMember]
public float value;
[DataMember( Name = "min")]
public float minValue;
[DataMember( Name = "max")]
public float maxValue;
[DataMember]
public uint count;
public GaugeNode(float value)
{
this.value = value;
minValue = value;
maxValue = value;
count = 1;
}
public void Update(float newValue)
{
minValue = Mathf.Min(minValue, newValue);
maxValue = Mathf.Max(maxValue, newValue);
value = newValue;
++count;
}
}
/// <summary>
/// A "stack" of timers that allows for lightweight hierarchical profiling of long-running processes.
/// <example>
/// Example usage:

/// This implements the Singleton pattern (solution 4) as described in
/// https://csharpindepth.com/articles/singleton
/// </remarks>
public class TimerStack : System.IDisposable
public class TimerStack : IDisposable
{
static readonly TimerStack k_Instance = new TimerStack();

public TimerNode RootNode
{
get { return m_RootNode; }
}
public void SetGauge(string name, float value)
{
if (!float.IsNaN(value))
{
GaugeNode gauge;
if (m_RootNode.Gauges.TryGetValue(name, out gauge))
{
gauge.Update(value);
}
else
{
m_RootNode.Gauges[name] = new GaugeNode(value);
}
}
}
void Push(string name)

1
UnitySDK/UnitySDK.sln.DotSettings


<s:Boolean x:Key="/Default/UserDictionary/Words/=protobuf/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Scaler/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Scriptable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=statsd/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=stddev/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=vals/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
正在加载...
取消
保存