a.ParallelAnimEvaluation

a.ParallelAnimEvaluation

#Overview

name: a.ParallelAnimEvaluation

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

It is referenced in 6 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of a.ParallelAnimEvaluation is to control whether animation evaluation in Unreal Engine 5 is run across the task graph system or purely on the game thread. This setting variable is primarily used for the animation system.

The Unreal Engine subsystem that relies on this setting variable is the animation system, specifically within the SkeletalMeshComponent and AnimInstance modules.

The value of this variable is set as a console variable with a default value of 1, meaning parallel animation evaluation is enabled by default. It can be changed at runtime using console commands.

This variable interacts closely with several other variables, including:

  1. CVarUseParallelAnimUpdate
  2. CVarForceUseParallelAnimUpdate
  3. CVarUseParallelAnimationInterpolation

Developers must be aware that:

  1. This variable affects performance and threading behavior of animation evaluation.
  2. It should be used in conjunction with other parallel animation variables for optimal performance.
  3. The effect may vary depending on the platform and whether threading for performance is supported.

Best practices when using this variable include:

  1. Testing performance with both enabled (1) and disabled (0) states to determine the optimal setting for your specific game.
  2. Ensuring that your animation blueprints and native animation code are thread-safe if using parallel evaluation.
  3. Considering the interaction with other parallel animation settings for a holistic approach to animation performance optimization.

Regarding the associated variable CVarUseParallelAnimationEvaluation:

The purpose of CVarUseParallelAnimationEvaluation is the same as a.ParallelAnimEvaluation. It’s an internal representation of the console variable used in the C++ code.

This variable is used in the AnimInstance and SkeletalMeshComponent modules to determine whether parallel animation evaluation should be performed.

The value is set by the a.ParallelAnimEvaluation console variable and can be accessed in C++ code using GetValueOnGameThread().

It interacts with the same variables as a.ParallelAnimEvaluation and is often used in conjunction with CVarUseParallelAnimUpdate and CVarUseParallelAnimationInterpolation to determine the overall parallelization strategy for animation processing.

Developers should be aware that this variable is used in conditional statements to determine the execution path of animation evaluation and update logic.

Best practices include consistently using this variable when implementing new animation-related features to ensure proper integration with the existing parallelization system.

#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:52

Scope: file

Source code excerpt:

#define LOCTEXT_NAMESPACE "SkeletalMeshComponent"

TAutoConsoleVariable<int32> CVarUseParallelAnimationEvaluation(TEXT("a.ParallelAnimEvaluation"), 1, TEXT("If 1, animation evaluation will be run across the task graph system. If 0, evaluation will run purely on the game thread"));
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"),

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimInstance.cpp:88

Scope: file

Source code excerpt:


extern TAutoConsoleVariable<int32> CVarUseParallelAnimUpdate;
extern TAutoConsoleVariable<int32> CVarUseParallelAnimationEvaluation;
extern TAutoConsoleVariable<int32> CVarForceUseParallelAnimUpdate;

ENGINE_API float RK4_SPRING_INTERPOLATOR_UPDATE_RATE = 60.f;
static FAutoConsoleVariableRef CVarRK4SpringInterpolatorUpdateRate(TEXT("p.RK4SpringInterpolator.UpdateRate"), RK4_SPRING_INTERPOLATOR_UPDATE_RATE, TEXT("RK4 Spring Interpolator's rate of update"), ECVF_Default);

ENGINE_API int32 RK4_SPRING_INTERPOLATOR_MAX_ITER = 4;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimInstance.cpp:795

Scope (from outer to inner):

file
function     bool UAnimInstance::NeedsImmediateUpdate

Source code excerpt:

#endif
		CVarUseParallelAnimUpdate.GetValueOnGameThread() == 0 ||
		CVarUseParallelAnimationEvaluation.GetValueOnGameThread() == 0 ||
		!bUseParallelUpdateAnimation ||
		DeltaSeconds == 0.0f;
}

bool UAnimInstance::NeedsUpdate() const
{

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

Scope: file

Source code excerpt:

#define LOCTEXT_NAMESPACE "SkeletalMeshComponent"

TAutoConsoleVariable<int32> CVarUseParallelAnimationEvaluation(TEXT("a.ParallelAnimEvaluation"), 1, TEXT("If 1, animation evaluation will be run across the task graph system. If 0, evaluation will run purely on the game thread"));
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"),

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

Scope (from outer to inner):

file
function     void USkeletalMeshComponent::RefreshBoneTransforms

Source code excerpt:

	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;
	const bool bDoParallelEvaluation = bHasValidInstanceForParallelWork && bDoPAE && (bShouldDoEvaluation || bShouldDoParallelInterpolation) && TickFunction && TickFunction->IsCompletionHandleValid();
	const bool bBlockOnTask = !bDoParallelEvaluation;  // If we aren't trying to do parallel evaluation then we

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

Scope (from outer to inner):

file
function     void USkeletalMeshComponent::DispatchParallelTickPose

Source code excerpt:


				// This duplicates *some* of the logic from RefreshBoneTransforms()
				const bool bDoPAE = !!CVarUseParallelAnimationEvaluation.GetValueOnGameThread() && (FApp::ShouldUseThreadingForPerformance() || FForkProcessHelper::SupportsMultithreadingPostFork());

				const bool bDoParallelUpdate = bDoPAE && TickFunction->IsCompletionHandleValid();

				const bool bBlockOnTask = !bDoParallelUpdate;   // If we aren't trying to do parallel update then we
																// will need to wait on an existing task.