Merge branch 'profiling' into actually_profiling
This commit is contained in:
commit
7fcc63c1b1
3 changed files with 52 additions and 15 deletions
|
@ -1,9 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
|
||||||
namespace Ryujinx.Profiler
|
namespace Ryujinx.Profiler
|
||||||
|
@ -48,38 +47,44 @@ namespace Ryujinx.Profiler
|
||||||
_history = history;
|
_history = history;
|
||||||
_cleanupRunning = true;
|
_cleanupRunning = true;
|
||||||
|
|
||||||
// Create low priority cleanup thread, it only cleans up RAM hence the low priority
|
// Create cleanup thread.
|
||||||
_cleanupThread = new Thread(CleanupLoop)
|
_cleanupThread = new Thread(CleanupLoop);
|
||||||
{
|
|
||||||
Priority = ThreadPriority.Lowest
|
|
||||||
};
|
|
||||||
_cleanupThread.Start();
|
_cleanupThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CleanupLoop()
|
private void CleanupLoop()
|
||||||
{
|
{
|
||||||
|
bool queueCleared = false;
|
||||||
|
|
||||||
while (_cleanupRunning)
|
while (_cleanupRunning)
|
||||||
{
|
{
|
||||||
// Ensure we only ever have 1 instance modifying timers or timerQueue
|
// Ensure we only ever have 1 instance modifying timers or timerQueue
|
||||||
if (Monitor.TryEnter(_timerQueueClearLock))
|
if (Monitor.TryEnter(_timerQueueClearLock))
|
||||||
{
|
{
|
||||||
ClearTimerQueue();
|
queueCleared = ClearTimerQueue();
|
||||||
|
|
||||||
foreach (var timer in Timers)
|
// Calculate before foreach to mitigate redundant calculations
|
||||||
{
|
long cleanupBefore = PerformanceCounter.ElapsedTicks - _history;
|
||||||
timer.Value.Cleanup(PerformanceCounter.ElapsedTicks - _history, _preserve - _history, _preserve);
|
long preserveStart = _preserve - _history;
|
||||||
}
|
|
||||||
|
// Each cleanup is self contained so run in parallel for maximum efficiency
|
||||||
|
Parallel.ForEach(Timers, (t) => t.Value.Cleanup(cleanupBefore, preserveStart, _preserve));
|
||||||
|
|
||||||
Monitor.Exit(_timerQueueClearLock);
|
Monitor.Exit(_timerQueueClearLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need to run too often
|
// Only sleep if queue was sucessfully cleared
|
||||||
Thread.Sleep(5);
|
if (queueCleared)
|
||||||
|
{
|
||||||
|
Thread.Sleep(5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearTimerQueue()
|
private bool ClearTimerQueue()
|
||||||
{
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
while (_timerQueue.TryDequeue(out var item))
|
while (_timerQueue.TryDequeue(out var item))
|
||||||
{
|
{
|
||||||
if (!Timers.TryGetValue(item.Config, out var value))
|
if (!Timers.TryGetValue(item.Config, out var value))
|
||||||
|
@ -96,7 +101,15 @@ namespace Ryujinx.Profiler
|
||||||
{
|
{
|
||||||
value.End(item.Time);
|
value.End(item.Time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't block for too long as memory disposal is blocked while this function runs
|
||||||
|
if (count++ > 10000)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FlagTime(TimingFlagType flagType)
|
public void FlagTime(TimingFlagType flagType)
|
||||||
|
|
|
@ -69,6 +69,27 @@ namespace Ryujinx.Profiler
|
||||||
return _cachedSession;
|
return _cachedSession;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This equals overload is vital
|
||||||
|
/// The default comparison is far too slow for the number of comparisons needed because it doesn't know what's important to compare
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Object to compare to</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (!(obj is ProfileConfig))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ProfileConfig cmpObj = (ProfileConfig)obj;
|
||||||
|
|
||||||
|
// Order here is important.
|
||||||
|
// Multiple entries with the same item is considerable less likely that multiple items with the same group.
|
||||||
|
// Likewise for group and category.
|
||||||
|
return (cmpObj.SessionItem == SessionItem &&
|
||||||
|
cmpObj.SessionGroup == SessionGroup &&
|
||||||
|
cmpObj.Category == Category);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -62,7 +62,10 @@ namespace Ryujinx.Profiler.UI
|
||||||
|
|
||||||
// Skip rendering out of bounds bars
|
// Skip rendering out of bounds bars
|
||||||
if (top < 0 || bottom > Height)
|
if (top < 0 || bottom > Height)
|
||||||
|
{
|
||||||
|
verticalIndex++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GL.Color3(Color.Green);
|
GL.Color3(Color.Green);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue