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.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ryujinx.Common;
|
||||
|
||||
namespace Ryujinx.Profiler
|
||||
|
@ -48,38 +47,44 @@ namespace Ryujinx.Profiler
|
|||
_history = history;
|
||||
_cleanupRunning = true;
|
||||
|
||||
// Create low priority cleanup thread, it only cleans up RAM hence the low priority
|
||||
_cleanupThread = new Thread(CleanupLoop)
|
||||
{
|
||||
Priority = ThreadPriority.Lowest
|
||||
};
|
||||
// Create cleanup thread.
|
||||
_cleanupThread = new Thread(CleanupLoop);
|
||||
_cleanupThread.Start();
|
||||
}
|
||||
|
||||
private void CleanupLoop()
|
||||
{
|
||||
bool queueCleared = false;
|
||||
|
||||
while (_cleanupRunning)
|
||||
{
|
||||
// Ensure we only ever have 1 instance modifying timers or timerQueue
|
||||
if (Monitor.TryEnter(_timerQueueClearLock))
|
||||
{
|
||||
ClearTimerQueue();
|
||||
queueCleared = ClearTimerQueue();
|
||||
|
||||
foreach (var timer in Timers)
|
||||
{
|
||||
timer.Value.Cleanup(PerformanceCounter.ElapsedTicks - _history, _preserve - _history, _preserve);
|
||||
}
|
||||
// Calculate before foreach to mitigate redundant calculations
|
||||
long cleanupBefore = PerformanceCounter.ElapsedTicks - _history;
|
||||
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);
|
||||
}
|
||||
|
||||
// No need to run too often
|
||||
Thread.Sleep(5);
|
||||
// Only sleep if queue was sucessfully cleared
|
||||
if (queueCleared)
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearTimerQueue()
|
||||
private bool ClearTimerQueue()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (_timerQueue.TryDequeue(out var item))
|
||||
{
|
||||
if (!Timers.TryGetValue(item.Config, out var value))
|
||||
|
@ -96,7 +101,15 @@ namespace Ryujinx.Profiler
|
|||
{
|
||||
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)
|
||||
|
|
|
@ -69,6 +69,27 @@ namespace Ryujinx.Profiler
|
|||
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>
|
||||
|
|
|
@ -62,7 +62,10 @@ namespace Ryujinx.Profiler.UI
|
|||
|
||||
// Skip rendering out of bounds bars
|
||||
if (top < 0 || bottom > Height)
|
||||
{
|
||||
verticalIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
GL.Color3(Color.Green);
|
||||
|
|
Loading…
Add table
Reference in a new issue