DEV Community

Cover image for How Can Unity Developers Trace Frame-Level CPU Bottlenecks More Precisely?
GameOptim
GameOptim

Posted on

How Can Unity Developers Trace Frame-Level CPU Bottlenecks More Precisely?

Introduction

When a Unity game shows a CPU performance anomaly, module-level statistics may not be enough to identify the actual cause. A function can be called repeatedly across consecutive frames, originate from another module, or appear as part of untracked profiling overhead.

The latest GameOptim GOT Online update addresses these cases with frame-level performance analysis, an Overhead breakdown, and cross-module function call tracking. The update also adds Unity Profiler-based rendering metrics, rendering resolution data, and asynchronous loading priority statistics to provide more context during performance analysis.

Summary

  • Frame-level analysis improves function curve precision to individual frames, making short CPU spikes and abnormal frame ranges easier to locate.
  • The new Overhead module separates untracked function time and SDK collection overhead from identified module costs.
  • Cross-module call paths help developers trace functions back to the root functions that actually triggered them.
  • Unity Profiler-based DrawCall, Batches, and Triangle statistics provide rendering information when OpenGL data cannot be obtained through the SDK.
  • Additional rendering and loading parameters provide more context for evaluating rendering configuration and scene-loading strategies.

How Does Frame-Level Analysis Help Find CPU Performance Problems?

The Overall Performance Trend section in GOT Online now supports frame-level analysis across its tabs, with function curve precision improved to individual frames.

This is particularly useful when a function is called continuously across multiple frames.

For example, when analyzing the UI module, developers can inspect the performance behavior of a function on each individual frame instead of relying only on a broader trend. The corresponding function stack is also available in the stack information area below the performance curve.

This makes it easier to answer questions such as:

  • Which specific frame contains the CPU spike?
  • Is a function consistently expensive across consecutive frames?
  • Does the abnormal cost occur only within a particular frame range?
  • Which functions are responsible for the observed cost?

The module timing statistics can also help developers identify relationships between different function modules and narrow down abnormal frames or time ranges more precisely.

Why Is the New Overhead Module Useful?

Module-level CPU statistics do not necessarily account for every piece of execution time.

The new Overhead module in GOT Online collects:

  • Untracked function execution time
  • Performance overhead generated by GameOptim's data collection

This distinction is useful when evaluating the actual contribution of different CPU costs to frame performance.

Instead of treating every measured cost as an optimization target, developers can use the Overhead breakdown to distinguish between key performance factors and secondary costs.

This can help avoid spending optimization effort on costs that have little practical impact.

What Can You See Inside Overhead?

After expanding the Overhead module, developers can inspect more detailed timing information for:

  • Untracked functions
  • SDK data collection overhead

This information can also help evaluate whether specific data collection modules should remain enabled during a test.

For example, developers can use the collected overhead information to assess the impact of modules such as Resources and Lua memory collection and adjust the profiling configuration when appropriate.

The goal is not simply to minimize profiling overhead, but to make the collection process better aligned with the performance question being investigated.

How Can Cross-Module Call Paths Reveal the Actual Root Function?

A function's performance cost does not always originate from the module where the function is displayed.

Previously, when analyzing the Animation performance page, developers could primarily observe calls under animation-related root functions. If an animation function was called by a root function belonging to another module, developers needed to switch to the corresponding module and inspect its parent function stack.

The updated Overall Performance Trend analysis makes this relationship easier to inspect.

In the Animation performance page, developers can enable "Animation function calls from other modules" from the upper-right corner. This allows animation functions called by functions from other modules to be displayed directly within the Animation analysis.

Developers can also click the call path next to a function name in the function stack to trace the animation function back to the root function that invoked it.

This provides a more complete view of the function call chain:

Root function → Cross-module call → Target function

Instead of optimizing the function where the cost becomes visible, developers can investigate the function that actually initiated the call.

Which New Rendering Metrics Are Available?

The update adds several additional performance parameters.

DrawCall, Batches, and Triangles

The Rendering module now provides DrawCall, Batches, and Triangle statistics based on the Unity Profiler.

This is particularly useful when the SDK cannot obtain OpenGL-related data. Developers can still inspect these rendering metrics during performance testing rather than losing visibility into basic rendering statistics.

These values provide additional context when investigating rendering-related performance behavior.

Rendering Resolution and Interval

The Rendering module also adds:

  • Rendering resolution width
  • Rendering resolution height
  • Rendering interval

These parameters make it easier to monitor the rendering configuration used during a test and correlate rendering settings with observed performance behavior.

How Can Loading Priority Help Analyze Scene Loading?

The Loading module now includes the configured asynchronous loading priority from Unity's Application.backgroundLoadingPriority.

This allows developers to inspect the loading priority configuration when evaluating scene loading time.

Rather than looking only at the final loading duration, developers can also check whether the current loading strategy leaves room for optimization through loading configuration.

What Should You Check First When Investigating a CPU Performance Issue?

A practical investigation flow based on these capabilities is:

  1. Locate the abnormal frame or time range.
    Use frame-level analysis to identify where the CPU performance anomaly occurs.

  2. Inspect the function stack.
    Determine which functions contribute to the observed cost instead of looking only at module-level totals.

  3. Check cross-module calls.
    If the function appears expensive within one module, verify whether it was actually triggered by a root function from another module.

  4. Review Overhead.
    Separate identified application costs from untracked functions and SDK collection overhead.

  5. Check rendering or loading parameters when relevant.
    Use DrawCall, Batches, Triangles, rendering resolution, rendering interval, or asynchronous loading priority to provide additional context.

  6. Prioritize the optimization target.
    Focus on the costs that materially contribute to the performance problem rather than treating every measured value as an optimization requirement.

Practical Recommendations

Problem What to inspect How it helps
Short CPU spike Frame-level function analysis Identifies the specific abnormal frame
Continuous function cost Per-frame function curve and stack Shows how the cost changes across frames
Unclear CPU attribution Overhead module Separates untracked time and SDK collection overhead
Function appears expensive in the wrong module Cross-module calls and call paths Helps trace the function back to its root caller
Rendering performance is unclear DrawCall, Batches, Triangles Provides additional rendering statistics
Rendering configuration may affect results Resolution and rendering interval Adds configuration context to performance data
Scene loading takes too long Application.backgroundLoadingPriority Helps evaluate the configured asynchronous loading strategy

Key Takeaways

  • Frame-level analysis is useful for short-lived CPU anomalies because it allows developers to inspect function behavior at individual-frame granularity.
  • Overhead should be separated from application-level costs so profiling overhead and untracked functions do not automatically become optimization targets.
  • Cross-module call paths matter when the visible bottleneck is not the root cause. Tracing the caller can reveal where the expensive function was actually triggered.
  • Rendering and loading parameters provide important context when analyzing DrawCalls, Batches, Triangles, rendering configuration, or scene loading.
  • Effective performance analysis depends not only on finding expensive functions, but also on understanding when they execute, what calls them, and what portion of the measured cost is actually relevant to the application.

FAQ

Does frame-level analysis replace the function stack?

No. Frame-level analysis shows when a function's performance cost occurs, while the function stack provides information about the functions involved in that execution. Using both together provides a more precise way to investigate abnormal frames.

What does the Overhead module include?

The Overhead module includes untracked function execution time and SDK data collection overhead generated during GameOptim testing. These values help developers distinguish measured overhead from identified application module costs.

Why should I check cross-module function calls?

A function displayed under one module may have been called by a root function belonging to another module. Cross-module call paths allow developers to trace the function back to its actual caller instead of investigating only the module where the cost becomes visible.

Can GOT Online show DrawCalls when OpenGL data is unavailable?

The updated Rendering module provides DrawCall, Batches, and Triangle statistics based on the Unity Profiler, allowing these rendering metrics to remain available when the SDK cannot obtain OpenGL data.

Why is Application.backgroundLoadingPriority useful for performance analysis?

The Loading module now records the configured asynchronous loading priority. This gives developers additional information when evaluating scene loading time and determining whether the loading strategy may provide an opportunity for optimization.

Top comments (0)