a.ParallelAnimInterpolation

a.ParallelAnimInterpolation

#Overview

name: a.ParallelAnimInterpolation

This variable is created as a Console Variable (cvar).

It is referenced in 5 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of a.ParallelAnimInterpolation is to control whether animation interpolation runs across the task graph system or purely on the game thread in Unreal Engine 5.

This setting variable is primarily used in the animation system of Unreal Engine 5. It specifically affects the SkeletalMeshComponent, which is a core part of the engine’s animation pipeline.

The value of this variable is set as a console variable, with a default value of 1. It can be changed at runtime through the console or programmatically.

The associated variable CVarUseParallelAnimationInterpolation directly interacts with a.ParallelAnimInterpolation. They share the same value and purpose.

Developers must be aware that:

  1. When set to 1, animation interpolation will run across the task graph system, potentially improving performance through parallelization.
  2. When set to 0, interpolation will run purely on the game thread, which might be necessary for certain debugging scenarios or if parallelization causes issues.

Best practices when using this variable include:

  1. Leave it at the default value (1) unless there’s a specific reason to disable parallel interpolation.
  2. When debugging animation issues, consider setting it to 0 to simplify the execution flow.
  3. Profile your game with both settings to determine which provides better performance for your specific use case.

Regarding the associated variable CVarUseParallelAnimationInterpolation:

Developers should be aware that changing this setting might interact with other parallelization settings in the animation system, and thorough testing should be done when modifying these values.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SkeletalMeshComponent.cpp:55

Scope: file

Source code excerpt:

TAutoConsoleVariable<int32> CVarUseParallelAnimUpdate(TEXT("a.ParallelAnimUpdate"), 1, TEXT("If != 0, then we update animation blend tree, native update, asset players and montages (is possible) on worker threads."));
TAutoConsoleVariable<int32> CVarForceUseParallelAnimUpdate(TEXT("a.ForceParallelAnimUpdate"), 0, TEXT("If != 0, then we update animations on worker threads regardless of the setting on the project or anim blueprint."));
TAutoConsoleVariable<int32> CVarUseParallelAnimationInterpolation(TEXT("a.ParallelAnimInterpolation"), 1, TEXT("If 1, animation interpolation will be run across the task graph system. If 0, interpolation will run purely on the game thread"));

static TAutoConsoleVariable<float> CVarStallParallelAnimation(
	TEXT("CriticalPathStall.ParallelAnimation"),
	0.0f,
	TEXT("Sleep for the given time in each parallel animation task. Time is given in ms. This is a debug option used for critical path analysis and forcing a change in the critical path."));

#Associated Variable and Callsites

This variable is associated with another variable named CVarUseParallelAnimationInterpolation. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SkeletalMeshComponent.cpp:55

Scope: file

Source code excerpt:

TAutoConsoleVariable<int32> CVarUseParallelAnimUpdate(TEXT("a.ParallelAnimUpdate"), 1, TEXT("If != 0, then we update animation blend tree, native update, asset players and montages (is possible) on worker threads."));
TAutoConsoleVariable<int32> CVarForceUseParallelAnimUpdate(TEXT("a.ForceParallelAnimUpdate"), 0, TEXT("If != 0, then we update animations on worker threads regardless of the setting on the project or anim blueprint."));
TAutoConsoleVariable<int32> CVarUseParallelAnimationInterpolation(TEXT("a.ParallelAnimInterpolation"), 1, TEXT("If 1, animation interpolation will be run across the task graph system. If 0, interpolation will run purely on the game thread"));

static TAutoConsoleVariable<float> CVarStallParallelAnimation(
	TEXT("CriticalPathStall.ParallelAnimation"),
	0.0f,
	TEXT("Sleep for the given time in each parallel animation task. Time is given in ms. This is a debug option used for critical path analysis and forcing a change in the critical path."));

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SkeletalMeshComponent.cpp:2448

Scope (from outer to inner):

file
function     void USkeletalMeshComponent::RefreshBoneTransforms

Source code excerpt:

	const bool bShouldDoInterpolation = TickFunction != nullptr && bDoEvaluationRateOptimization && !bInvalidCachedBones && bShouldInterpolateSkippedFrames;

	const bool bShouldDoParallelInterpolation = bShouldDoInterpolation && CVarUseParallelAnimationInterpolation.GetValueOnGameThread() == 1;

	const bool bDoPAE = !!CVarUseParallelAnimationEvaluation.GetValueOnGameThread() && (FApp::ShouldUseThreadingForPerformance() || FForkProcessHelper::SupportsMultithreadingPostFork());

	const bool bMainInstanceValidForParallelWork = AnimScriptInstance == nullptr || AnimScriptInstance->CanRunParallelWork();
	const bool bPostInstanceValidForParallelWork = PostProcessAnimInstance == nullptr || PostProcessAnimInstance->CanRunParallelWork();
	const bool bHasValidInstanceForParallelWork = HasValidAnimationInstance() && bMainInstanceValidForParallelWork && bPostInstanceValidForParallelWork;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SkeletalMeshComponent.cpp:2710

Scope (from outer to inner):

file
function     void USkeletalMeshComponent::PostAnimEvaluation

Source code excerpt:

	}

	if(CVarUseParallelAnimationInterpolation.GetValueOnGameThread() == 0)
	{
		if (EvaluationContext.bDuplicateToCacheCurve)
		{
			CachedCurve.CopyFrom(AnimCurves);
		}
		

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SkeletalMeshComponent.cpp:4119

Scope (from outer to inner):

file
function     void USkeletalMeshComponent::ParallelDuplicateAndInterpolate

Source code excerpt:

void USkeletalMeshComponent::ParallelDuplicateAndInterpolate(FAnimationEvaluationContext& InAnimEvaluationContext)
{
	if(CVarUseParallelAnimationInterpolation.GetValueOnAnyThread() != 0)
	{
		if (InAnimEvaluationContext.bDuplicateToCacheCurve)
		{
			InAnimEvaluationContext.CachedCurve.CopyFrom(InAnimEvaluationContext.Curve);
		}