No more stopwatches created, uses PerformanceCounter now
This commit is contained in:
parent
6f87bd0bc1
commit
73c89c8f3b
7 changed files with 26 additions and 54 deletions
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using Ryujinx.Common;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
@ -16,8 +17,8 @@ namespace Ryujinx.Profiler
|
||||||
$"{time.Key.SessionGroup}," +
|
$"{time.Key.SessionGroup}," +
|
||||||
$"{time.Key.SessionItem}," +
|
$"{time.Key.SessionItem}," +
|
||||||
$"{time.Value.Count}," +
|
$"{time.Value.Count}," +
|
||||||
$"{Profile.ConvertTicksToMS(time.Value.AverageTime)}," +
|
$"{time.Value.AverageTime / PerformanceCounter.TicksPerMillisecond}," +
|
||||||
$"{Profile.ConvertTicksToMS(time.Value.TotalTime)}\r\n";
|
$"{time.Value.TotalTime / PerformanceCounter.TicksPerMillisecond}\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure file directory exists before write
|
// Ensure file directory exists before write
|
||||||
|
|
|
@ -4,14 +4,12 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Ryujinx.Common;
|
||||||
|
|
||||||
namespace Ryujinx.Profiler
|
namespace Ryujinx.Profiler
|
||||||
{
|
{
|
||||||
public class InternalProfile
|
public class InternalProfile
|
||||||
{
|
{
|
||||||
public long CurrentTime => SW.ElapsedTicks;
|
|
||||||
|
|
||||||
private Stopwatch SW;
|
|
||||||
internal ConcurrentDictionary<ProfileConfig, TimingInfo> Timers;
|
internal ConcurrentDictionary<ProfileConfig, TimingInfo> Timers;
|
||||||
|
|
||||||
private readonly object _sessionLock = new object();
|
private readonly object _sessionLock = new object();
|
||||||
|
@ -45,9 +43,6 @@ namespace Ryujinx.Profiler
|
||||||
Priority = ThreadPriority.Lowest
|
Priority = ThreadPriority.Lowest
|
||||||
};
|
};
|
||||||
_cleanupThread.Start();
|
_cleanupThread.Start();
|
||||||
|
|
||||||
SW = new Stopwatch();
|
|
||||||
SW.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CleanupLoop()
|
private void CleanupLoop()
|
||||||
|
@ -56,7 +51,7 @@ namespace Ryujinx.Profiler
|
||||||
{
|
{
|
||||||
foreach (var timer in Timers)
|
foreach (var timer in Timers)
|
||||||
{
|
{
|
||||||
timer.Value.Cleanup(SW.ElapsedTicks - _history, _preserve - _history, _preserve);
|
timer.Value.Cleanup(PerformanceCounter.ElapsedTicks - _history, _preserve - _history, _preserve);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need to run too often
|
// No need to run too often
|
||||||
|
@ -69,7 +64,7 @@ namespace Ryujinx.Profiler
|
||||||
_timingFlags[_timingFlagIndex] = new TimingFlag()
|
_timingFlags[_timingFlagIndex] = new TimingFlag()
|
||||||
{
|
{
|
||||||
FlagType = flagType,
|
FlagType = flagType,
|
||||||
Timestamp = SW.ElapsedTicks
|
Timestamp = PerformanceCounter.ElapsedTicks
|
||||||
};
|
};
|
||||||
|
|
||||||
if (++_timingFlagIndex >= MaxFlags)
|
if (++_timingFlagIndex >= MaxFlags)
|
||||||
|
@ -84,14 +79,14 @@ namespace Ryujinx.Profiler
|
||||||
|
|
||||||
public void BeginProfile(ProfileConfig config)
|
public void BeginProfile(ProfileConfig config)
|
||||||
{
|
{
|
||||||
Timers.GetOrAdd(config, profileConfig => new TimingInfo()).Begin(SW.ElapsedTicks);
|
Timers.GetOrAdd(config, profileConfig => new TimingInfo()).Begin(PerformanceCounter.ElapsedTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndProfile(ProfileConfig config)
|
public void EndProfile(ProfileConfig config)
|
||||||
{
|
{
|
||||||
if (Timers.TryGetValue(config, out var timingInfo))
|
if (Timers.TryGetValue(config, out var timingInfo))
|
||||||
{
|
{
|
||||||
timingInfo.End(SW.ElapsedTicks);
|
timingInfo.End(PerformanceCounter.ElapsedTicks);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -113,7 +108,7 @@ namespace Ryujinx.Profiler
|
||||||
{
|
{
|
||||||
Dictionary<ProfileConfig, TimingInfo> outDict = new Dictionary<ProfileConfig, TimingInfo>();
|
Dictionary<ProfileConfig, TimingInfo> outDict = new Dictionary<ProfileConfig, TimingInfo>();
|
||||||
|
|
||||||
_preserve = SW.ElapsedTicks;
|
_preserve = PerformanceCounter.ElapsedTicks;
|
||||||
|
|
||||||
// Forcibly get copy so user doesn't block profiling
|
// Forcibly get copy so user doesn't block profiling
|
||||||
ProfileConfig[] configs = Timers.Keys.ToArray();
|
ProfileConfig[] configs = Timers.Keys.ToArray();
|
||||||
|
|
|
@ -107,21 +107,6 @@ namespace Ryujinx.Profiler
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double ConvertTicksToMS(long ticks)
|
|
||||||
{
|
|
||||||
return (((double)ticks) / Stopwatch.Frequency) * 1000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long ConvertSecondsToTicks(double seconds)
|
|
||||||
{
|
|
||||||
return (long)(seconds * Stopwatch.Frequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long ConvertMSToTicks(double ms)
|
|
||||||
{
|
|
||||||
return (long)((ms / 1000) * Stopwatch.Frequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<ProfileConfig, TimingInfo> GetProfilingData()
|
public static Dictionary<ProfileConfig, TimingInfo> GetProfilingData()
|
||||||
{
|
{
|
||||||
#if USE_PROFILING
|
#if USE_PROFILING
|
||||||
|
@ -143,16 +128,5 @@ namespace Ryujinx.Profiler
|
||||||
return new TimingFlag[0];
|
return new TimingFlag[0];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long GetCurrentTime()
|
|
||||||
{
|
|
||||||
#if USE_PROFILING
|
|
||||||
if (!ProfilingEnabled())
|
|
||||||
return 0;
|
|
||||||
return _profileInstance.CurrentTime;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Profiler.UI.SharpFontHelpers;
|
using Ryujinx.Profiler.UI.SharpFontHelpers;
|
||||||
|
|
||||||
namespace Ryujinx.Profiler.UI
|
namespace Ryujinx.Profiler.UI
|
||||||
|
@ -234,7 +235,7 @@ namespace Ryujinx.Profiler.UI
|
||||||
{
|
{
|
||||||
_updateTimer = 0;
|
_updateTimer = 0;
|
||||||
_unsortedProfileData = Profile.GetProfilingData().ToList();
|
_unsortedProfileData = Profile.GetProfilingData().ToList();
|
||||||
_captureTime = Profile.GetCurrentTime();
|
_captureTime = PerformanceCounter.ElapsedTicks;
|
||||||
_timingFlags = Profile.GetTimingFlags();
|
_timingFlags = Profile.GetTimingFlags();
|
||||||
_profileUpdated = true;
|
_profileUpdated = true;
|
||||||
_doStep = false;
|
_doStep = false;
|
||||||
|
@ -503,9 +504,9 @@ namespace Ryujinx.Profiler.UI
|
||||||
foreach (var entry in _sortedProfileData)
|
foreach (var entry in _sortedProfileData)
|
||||||
{
|
{
|
||||||
float y = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex++);
|
float y = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex++);
|
||||||
_fontService.DrawText($"{Profile.ConvertTicksToMS(entry.Value.Instant):F3} ({entry.Value.InstantCount})", xOffset, y, LineHeight);
|
_fontService.DrawText($"{entry.Value.Instant / PerformanceCounter.TicksPerMillisecond:F3} ({entry.Value.InstantCount})", xOffset, y, LineHeight);
|
||||||
_fontService.DrawText($"{Profile.ConvertTicksToMS(entry.Value.AverageTime):F3}", 150 + xOffset, y, LineHeight);
|
_fontService.DrawText($"{entry.Value.AverageTime / PerformanceCounter.TicksPerMillisecond:F3}", 150 + xOffset, y, LineHeight);
|
||||||
_fontService.DrawText($"{Profile.ConvertTicksToMS(entry.Value.TotalTime):F3}", 260 + xOffset, y, LineHeight);
|
_fontService.DrawText($"{entry.Value.TotalTime / PerformanceCounter.TicksPerMillisecond:F3}", 260 + xOffset, y, LineHeight);
|
||||||
|
|
||||||
totalInstant += entry.Value.Instant;
|
totalInstant += entry.Value.Instant;
|
||||||
totalAverage += entry.Value.AverageTime;
|
totalAverage += entry.Value.AverageTime;
|
||||||
|
@ -527,9 +528,9 @@ namespace Ryujinx.Profiler.UI
|
||||||
|
|
||||||
// Totals
|
// Totals
|
||||||
yHeight = FilterHeight + 2;
|
yHeight = FilterHeight + 2;
|
||||||
_fontService.DrawText($"{Profile.ConvertTicksToMS(totalInstant):F3} ({totalCount})", xOffset, yHeight, TitleFontHeight);
|
_fontService.DrawText($"{totalInstant / PerformanceCounter.TicksPerMillisecond:F3} ({totalCount})", xOffset, yHeight, TitleFontHeight);
|
||||||
_fontService.DrawText($"{Profile.ConvertTicksToMS(totalAverage):F3}", 150 + xOffset, yHeight, TitleFontHeight);
|
_fontService.DrawText($"{totalAverage / PerformanceCounter.TicksPerMillisecond:F3}", 150 + xOffset, yHeight, TitleFontHeight);
|
||||||
_fontService.DrawText($"{Profile.ConvertTicksToMS(totalTime):F3}", 260 + xOffset, yHeight, TitleFontHeight);
|
_fontService.DrawText($"{totalTime / PerformanceCounter.TicksPerMillisecond:F3}", 260 + xOffset, yHeight, TitleFontHeight);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
using Ryujinx.Common;
|
||||||
|
|
||||||
namespace Ryujinx.Profiler.UI
|
namespace Ryujinx.Profiler.UI
|
||||||
{
|
{
|
||||||
|
@ -25,13 +26,13 @@ namespace Ryujinx.Profiler.UI
|
||||||
float barHeight = (LineHeight - LinePadding);
|
float barHeight = (LineHeight - LinePadding);
|
||||||
long history = Profile.HistoryLength;
|
long history = Profile.HistoryLength;
|
||||||
long timeWidthTicks = (long)(history / (double)_graphZoom);
|
long timeWidthTicks = (long)(history / (double)_graphZoom);
|
||||||
long graphPositionTicks = Profile.ConvertMSToTicks(_graphPosition);
|
long graphPositionTicks = (long)(_graphPosition * PerformanceCounter.TicksPerMillisecond);
|
||||||
|
|
||||||
// Reset start point if out of bounds
|
// Reset start point if out of bounds
|
||||||
if (timeWidthTicks + graphPositionTicks > history)
|
if (timeWidthTicks + graphPositionTicks > history)
|
||||||
{
|
{
|
||||||
graphPositionTicks = history - timeWidthTicks;
|
graphPositionTicks = history - timeWidthTicks;
|
||||||
_graphPosition = (float)Profile.ConvertTicksToMS(graphPositionTicks);
|
_graphPosition = (float)graphPositionTicks / PerformanceCounter.TicksPerMillisecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw timing flags
|
// Draw timing flags
|
||||||
|
@ -112,7 +113,7 @@ namespace Ryujinx.Profiler.UI
|
||||||
float labelWidth = _fontService.DrawText(label, 0, 0, LineHeight, false);
|
float labelWidth = _fontService.DrawText(label, 0, 0, LineHeight, false);
|
||||||
_fontService.DrawText(label, xOffset + width - labelWidth - LinePadding, FilterHeight + LinePadding, LineHeight);
|
_fontService.DrawText(label, xOffset + width - labelWidth - LinePadding, FilterHeight + LinePadding, LineHeight);
|
||||||
|
|
||||||
_fontService.DrawText($"-{MathF.Round((float)(Profile.ConvertTicksToMS(timeWidthTicks) + _graphPosition), 2)} ms", xOffset + LinePadding, FilterHeight + LinePadding, LineHeight);
|
_fontService.DrawText($"-{MathF.Round((float)((timeWidthTicks / PerformanceCounter.TicksPerMillisecond) + _graphPosition), 2)} ms", xOffset + LinePadding, FilterHeight + LinePadding, LineHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
using Ryujinx.Common;
|
||||||
|
|
||||||
namespace Ryujinx.Profiler.UI
|
namespace Ryujinx.Profiler.UI
|
||||||
{
|
{
|
||||||
|
@ -12,7 +13,6 @@ namespace Ryujinx.Profiler.UI
|
||||||
private bool _profilerRunning;
|
private bool _profilerRunning;
|
||||||
|
|
||||||
// Timing
|
// Timing
|
||||||
private Stopwatch _sw;
|
|
||||||
private double _prevTime;
|
private double _prevTime;
|
||||||
|
|
||||||
public ProfileWindowManager()
|
public ProfileWindowManager()
|
||||||
|
@ -21,7 +21,6 @@ namespace Ryujinx.Profiler.UI
|
||||||
{
|
{
|
||||||
_profilerRunning = true;
|
_profilerRunning = true;
|
||||||
_prevTime = 0;
|
_prevTime = 0;
|
||||||
_sw = Stopwatch.StartNew();
|
|
||||||
_profileThread = new Thread(ProfileLoop);
|
_profileThread = new Thread(ProfileLoop);
|
||||||
_profileThread.Start();
|
_profileThread.Start();
|
||||||
}
|
}
|
||||||
|
@ -59,7 +58,7 @@ namespace Ryujinx.Profiler.UI
|
||||||
|
|
||||||
while (_profilerRunning)
|
while (_profilerRunning)
|
||||||
{
|
{
|
||||||
double time = _sw.ElapsedMilliseconds / 1000.0;
|
double time = (double)PerformanceCounter.ElapsedTicks / PerformanceCounter.TicksPerSecond;
|
||||||
_window.Update(new FrameEventArgs(time - _prevTime));
|
_window.Update(new FrameEventArgs(time - _prevTime));
|
||||||
_prevTime = time;
|
_prevTime = time;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Ryujinx.Profiler;
|
using Ryujinx.Profiler;
|
||||||
using Ryujinx.Ui;
|
using Ryujinx.Ui;
|
||||||
|
using Ryujinx.Common;
|
||||||
|
|
||||||
namespace Ryujinx
|
namespace Ryujinx
|
||||||
{
|
{
|
||||||
|
@ -73,7 +74,7 @@ namespace Ryujinx
|
||||||
FileDumpEnabled = profilePath != "",
|
FileDumpEnabled = profilePath != "",
|
||||||
DumpLocation = profilePath,
|
DumpLocation = profilePath,
|
||||||
UpdateRate = (float)((updateRateHz <= 0) ? -1 : 1.0f / updateRateHz),
|
UpdateRate = (float)((updateRateHz <= 0) ? -1 : 1.0f / updateRateHz),
|
||||||
History = Profile.ConvertSecondsToTicks(Convert.ToDouble(parser.Value("Profiling_History"))),
|
History = (long)(Convert.ToDouble(parser.Value("Profiling_History")) * PerformanceCounter.TicksPerSecond),
|
||||||
});
|
});
|
||||||
|
|
||||||
SystemLanguage SetLanguage = Enum.Parse<SystemLanguage>(parser.Value("System_Language"));
|
SystemLanguage SetLanguage = Enum.Parse<SystemLanguage>(parser.Value("System_Language"));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue