-
Notifications
You must be signed in to change notification settings - Fork 316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NEW: Input System Profiler Module #2038
base: develop
Are you sure you want to change the base?
Conversation
var controlCount = ProfilerDriver.GetFormattedCounterValue(selectedFrameIndex, | ||
InputStatistics.Category.Name, InputStatistics.ControlCountName); | ||
|
||
m_UpdateCountLabel.text = $"{InputStatistics.UpdateCountName}: {updateCount}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a basic label list at the moment. Is it possible to pass any extra information via the profiler API? Or extract sample data to e.g. create a distribution within detail window?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a ProfilerRecorder that you can use to gather samples, which then allows you to do more statistical computations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ekcoh it seems to be possible to add more complex UITK elements. I think a list can be fine for now, and then we could add a nicer UI using UITK (there's more info here , which you probably have seen; and a more more complex UI example in this package where this is the result:
{ | ||
try | ||
{ | ||
DoUpdate(updateType, ref eventBuffer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs more work to extract some stuff from DoUpdate below
InputStatistics.EventSize.Value += totalEventSizeBytes; | ||
InputStatistics.AverageLatency.Value += ((totalEventLag / totalEventCount) * 1e9); | ||
InputStatistics.MaxLatency.Value += (maxEventLag * 1e9); | ||
InputStatistics.EventProcessingTime.Value += eventProcessingTime * 1e9; // TODO Possible to replace Stopwatch with marker somehow? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this last line here is an anti pattern, ideally I would like to include the Update profiler marker into the profiler module, is this possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During hackweek I used StopWatch. It was preallocated and reset and reused every frame and accumulated in a ProfilerCounter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which is what it looks like you're doing here :)
My first thought looking at the window is the mix of types being presented. I see Counters, Memory Size, and Times. It looks a little bit busy and hard to know what I'm looking at exactly. Overall I think this is a great idea. I wonder if there's a way we can group like values together within one window. |
Agreed, I just saw other modules were doing that and replicated it. I think there is opportunity to slip things into separate modules to handle it, e.g. Latency and Input System Counters. I wonder if execution time should even be there since its covered by the ProfilerMarkers anyway..... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work in adding this functionality.
I think this could easily land in an experimental kind of namespace, almost as is. Just with small tweaks IMO.
The only issue I have is from a UI perspective. Similar to what @surfnerd mentioned, the Module UI is a bit confusing with all the Counts, Bytes, Timings.
I think we could put the Bytes and Timings statistics only in the panel label for now. In my opinion the count statistics are better suited for the "line" UI type.
Ideally, the best would be to have some kind of "Timeline" similar to what CPU has (see img below). But we don't need to be perfect for this to land as I don't think it adds a big risk. I think this would already provide benefit and we could just improve the parts that are confusing a little bit. But of course, we should ask ourselves what are trying to solve with this and see if this
I will try to play around a bit with this this sprint and see if I can improve anything.
/// <summary> | ||
/// Input Statistics for Unity Profiler integration. | ||
/// </summary> | ||
internal static class InputStatistics |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd create a Editor/Internal/Profiler
folder and but everything in there. I find odd to have this class next to a bunch of "Utilities" classes.
var controlCount = ProfilerDriver.GetFormattedCounterValue(selectedFrameIndex, | ||
InputStatistics.Category.Name, InputStatistics.ControlCountName); | ||
|
||
m_UpdateCountLabel.text = $"{InputStatistics.UpdateCountName}: {updateCount}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ekcoh it seems to be possible to add more complex UITK elements. I think a list can be fine for now, and then we could add a nicer UI using UITK (there's more info here , which you probably have seen; and a more more complex UI example in this package where this is the result:
@@ -2,7 +2,8 @@ | |||
"name": "Unity.InputSystem", | |||
"rootNamespace": "", | |||
"references": [ | |||
"Unity.ugui" | |||
"Unity.ugui", | |||
"Unity.Profiling.Core" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if this might create some overhead? Probably we could set a define like INPUTSYSTEM_USE_CUSTOMPROFILER
or something similar, in case users don't want to have this code in their release builds.
@@ -3055,6 +3058,10 @@ internal bool ShouldRunUpdate(InputUpdateType updateType) | |||
return (updateType & mask) != 0; | |||
} | |||
|
|||
struct UpdateMetrics |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To remove?
if (currentEventTimeInternal <= currentTime) | ||
totalEventLag += currentTime - currentEventTimeInternal; | ||
++m_Metrics.totalEventCount; | ||
m_Metrics.totalEventBytes += (int)currentEventReadPtr->sizeInBytes; | ||
{ | ||
var lag = currentTime - currentEventTimeInternal; | ||
totalEventLag += lag; | ||
if (lag > maxEventLag) | ||
maxEventLag = lag; | ||
} | ||
++totalEventCount; | ||
totalEventSizeBytes += (int)currentEventReadPtr->sizeInBytes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This a bit more complex so I would extract this to a method, as OnUpdate
is already big enoug.
m_Metrics.totalEventLagTime += totalEventLag; | ||
|
||
ResetCurrentProcessedEventBytesForDevices(); | ||
// Profiler counters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add a comment that these counters are PerFrame, as we can call update more than once?
Or Maybe a prefix of something like InputStatistics.EventCountPerFrame.Value
or PerUpdate
, something like that.
Also if could we use ProfileRecorder
for this?
"com.unity.settings-manager": "1.0.3", | ||
"com.unity.test-framework": "1.4.5", | ||
"com.unity.test-framework.build": "0.0.1-preview.12", | ||
"com.unity.test-framework.performance": "3.0.3", | ||
"com.unity.test-framework.utp-reporter": "1.1.0-preview", | ||
"com.unity.textmeshpro": "2.1.4", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why this is removed?
Description
Made a draft implementation of a Profiler Module for the Input System based on lack of observability to work as an aid in understanding system mechanics. Hopefully could work as an embryo of something more refined if considered a good idea.
Testing status & QA
Just a prototype at this point. Try it out and suggest or contribute to this PR to make it more useful.
Overall Product Risks
Some more work likely need to be done to InputManager.OnUpdate to make that method cleaner and this work more reliably.
Might not be possible to merge unless minimum Unity version requirement is changed to 2020.1. (Profiler package dependency)
Comments to reviewers
At this point mainly looking for feedback and suggestions since this was unplanned work.
Checklist
Before review:
Changed
,Fixed
,Added
sections.Area_CanDoX
,Area_CanDoX_EvenIfYIsTheCase
,Area_WhenIDoX_AndYHappens_ThisIsTheResult
.During merge:
NEW: ___
.FIX: ___
.DOCS: ___
.CHANGE: ___
.RELEASE: 1.1.0-preview.3
.After merge: