UPCGSettings::GetSettingsCrc() recomputes full object CRC on every call in non-editor builds, causing 500ms+ GT spikes when PostExecutePrimaryLoopElement iterates over large point sets

UPCGSettings::GetSettingsCrc() uses a cached CRC in editor builds (CachedCrc member, guarded by WITH_EDITORONLY_DATA) but recomputes from scratch via FPCGSettingsObjectCrc::PCGCrc(this) on every call in non-editor builds. The comment states: “In non-editor builds we don’t track changes to the UPCGSettings object so we always compute it.”

This is correct for single calls, but IPCGElement::PostExecutePrimaryLoopElement (PCGElement.cpp ~line 722) calls GetDependenciesCrc - which calls GetSettingsCrc inside a loop over PrimaryDataCollections. For elements with large output sets (e.g. FPCGSplineSampler Element producing 2000+ points), the same settings CRC is recomputed 2000+ times. Each call serializes the entire UPCGSettings object at ~0.25ms per call in our setup.

The settings object is immutable at runtime it’s a cooked UDataAsset. The CRC result is identical on every call within the loop. The per-point input data CRC (which changes per iteration) is computed separately via SubCollection.ComputeCrcs().

Note that this issue is not present in editor builds as the result is already cached. We have simply exposed this path in non editor builds also and the frame spikes (around 500ms on our min spec) have disappeared. This seems like a viable fix

[Attachment Removed]

Steps to Reproduce

  1. Create a PCG graph with a PCGSplineSampler node that produces 2000+ output points
  2. Configure runtime generation so the graph executes during gameplay (e.g. player traversal triggers PCG generation)
  3. Build a non-editor target (Development or Test)
  4. Run the game and trigger the PCG generation
  5. Capture a CPU trace (Unreal Insights or -trace=cpu)
  6. Observe IPCGElement::GetDependenciesCrc taking scaling linearly with output point count per frame where the element’s PostExecutePrimaryLoopElement runs
    [Attachment Removed]

Hi James.

Sorry for the late answer, but it’s a good observation.

We’re a bit late to get a fix for that in the release (but maybe in a hotfix) - I’ll keep a note.

Preferably, we’d cache that locally for that loop.

To be clear, this isn’t about the point count rather than the data count, because the primary loop is done on a per-data basis.

If that is a problem for you, you can easily disable it with pcg.AllowPerDataCaching too.

However, in general, CRC computation isn’t cheap, so depending on your use case, you can disable the cache completely (incl. CRC computations) at runtime, which might be better.

The cvar for this is pcg.Cache.Runtime.Enabled.

Let me know if you have more questions.

Cheers,

Julien

[Attachment Removed]