p.Chaos.XPBDSpring.ParallelConstraintCount
p.Chaos.XPBDSpring.ParallelConstraintCount
#Overview
name: p.Chaos.XPBDSpring.ParallelConstraintCount
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
If we have more constraints than this, use parallel-for in Apply.
It is referenced in 12
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of p.Chaos.XPBDSpring.ParallelConstraintCount is to determine when to use parallel processing for XPBD (Extended Position Based Dynamics) spring constraints in the Chaos physics engine of Unreal Engine 5. It sets a threshold for the number of constraints that, when exceeded, triggers parallel computation.
This setting variable is primarily used in the Chaos physics engine, specifically in the XPBD spring constraint system. It’s part of the Experimental Chaos module in Unreal Engine 5’s runtime.
The value of this variable is set to 100 by default, as seen in the source code:
int32 Chaos_XPBDSpring_ParallelConstraintCount = 100;
It’s also exposed as a console variable, allowing runtime modification:
FAutoConsoleVariableRef CVarChaosXPBDSpringParallelConstraintCount(TEXT("p.Chaos.XPBDSpring.ParallelConstraintCount"), Chaos_XPBDSpring_ParallelConstraintCount, TEXT("If we have more constraints than this, use parallel-for in Apply."));
This variable interacts closely with the constraint system, particularly in the Apply() and UpdateLinearSystem() functions of various spring constraint classes (FXPBDSpringConstraints, FXPBDAnisotropicEdgeSpringConstraints, FXPBDAnisotropicAxialSpringConstraints).
Developers should be aware that this variable affects performance and parallelism. Setting it too low might lead to unnecessary parallelization overhead for small constraint sets, while setting it too high might underutilize available parallel processing capabilities.
Best practices when using this variable include:
- Profiling the application to determine the optimal threshold for your specific use case.
- Consider the target hardware capabilities when setting this value.
- Be cautious when modifying this value at runtime, as it can significantly impact performance.
The associated variable Chaos_XPBDSpring_ParallelConstraintCount is used internally within the Chaos physics engine and shares the same value and purpose as p.Chaos.XPBDSpring.ParallelConstraintCount. It’s used directly in the code to check if parallel processing should be employed. The same considerations and best practices apply to this internal variable.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDSpringConstraints.cpp:30
Scope (from outer to inner):
file
namespace Chaos::Softs
Source code excerpt:
int32 Chaos_XPBDSpring_ParallelConstraintCount = 100;
#if !UE_BUILD_SHIPPING
FAutoConsoleVariableRef CVarChaosXPBDSpringParallelConstraintCount(TEXT("p.Chaos.XPBDSpring.ParallelConstraintCount"), Chaos_XPBDSpring_ParallelConstraintCount, TEXT("If we have more constraints than this, use parallel-for in Apply."));
int32 Chaos_XPBDSpring_SplitDampingMode = (int32)EXPBDSplitDampingMode::TwoPassBefore;
FAutoConsoleVariableRef CVarChaosXPBDSpringSplitDamping(TEXT("p.Chaos.XPBDSpring.SplitDamping"), Chaos_XPBDSpring_SplitDampingMode, TEXT("Test xpbd spring split damping mode. 0 = single lambda, 1 = interleaved with damping after (non-ispc only), 2 interleaved with damping before (non-ispc only), 3 = two passes damping after (non-ispc only), 4 = two passes damping before (default)."));
#endif
template<typename SolverParticlesOrRange>
#Associated Variable and Callsites
This variable is associated with another variable named Chaos_XPBDSpring_ParallelConstraintCount
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDAnisotropicSpringConstraints.cpp:23
Scope: file
Source code excerpt:
// @todo(chaos): the parallel threshold (or decision to run parallel) should probably be owned by the solver and passed to the constraint container
extern int32 Chaos_XPBDSpring_ParallelConstraintCount;
namespace Private
{
static void UpdateDists(const TArray<FSolverReal>& BaseDists, const TArray<FSolverVec2>& WarpWeftScaleBaseMultipliers, const FPBDWeightMap& WarpScale, const FPBDWeightMap& WeftScale, TArray<FSolverReal>& Dists)
{
const bool WarpScaleHasWeightMap = WarpScale.HasWeightMap();
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDAnisotropicSpringConstraints.cpp:259
Scope: file
Source code excerpt:
// In dev builds we always color so we can tune the system without restarting. See Apply()
#if UE_BUILD_SHIPPING || UE_BUILD_TEST
if (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount)
#endif
{
const TArray<TArray<int32>> ConstraintsPerColor = FGraphColoring::ComputeGraphColoringParticlesOrRange(Constraints, InParticles, ParticleOffset, ParticleOffset + ParticleCount);
// Reorder constraints based on color so each array in ConstraintsPerColor contains contiguous elements.
TArray<TVec2<int32>> ReorderedConstraints;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDAnisotropicSpringConstraints.cpp:367
Scope (from outer to inner):
file
function void FXPBDAnisotropicEdgeSpringConstraints::Apply
Source code excerpt:
const bool DampingHasWeightMap = DampingRatio.HasWeightMap();
if ((ConstraintsPerColorStartIndex.Num() > 1) && (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount))
{
const int32 ConstraintColorNum = ConstraintsPerColorStartIndex.Num() - 1;
#if INTEL_ISPC
if (bRealTypeCompatibleWithISPC && bChaos_XPBDSpring_ISPC_Enabled)
{
const bool bSingleLambda = Chaos_XPBDSpring_SplitDampingMode == (int32)EXPBDSplitDampingMode::SingleLambda;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDAnisotropicSpringConstraints.cpp:849
Scope (from outer to inner):
file
function void FXPBDAnisotropicEdgeSpringConstraints::UpdateLinearSystem
Source code excerpt:
const bool StiffnessBiasHasWeightMap = StiffnessBias.HasWeightMap();
const bool DampingHasWeightMap = DampingRatio.HasWeightMap();
if ((ConstraintsPerColorStartIndex.Num() > 1) && (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount))
{
const int32 ConstraintColorNum = ConstraintsPerColorStartIndex.Num() - 1;
if (!StiffnessHasWeightMap && !StiffnessWeftHasWeightMap && !StiffnessBiasHasWeightMap && !DampingHasWeightMap)
{
const FSolverVec3 ExpStiffnessValue((FSolverReal)StiffnessWeft, (FSolverReal)StiffnessWarp, (FSolverReal)StiffnessBias);
const FSolverReal DampingRatioValue = (FSolverReal)DampingRatio;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDAnisotropicSpringConstraints.cpp:1147
Scope (from outer to inner):
file
function void FXPBDAnisotropicAxialSpringConstraints::InitColor
Source code excerpt:
// In dev builds we always color so we can tune the system without restarting. See Apply()
#if UE_BUILD_SHIPPING || UE_BUILD_TEST
if (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount)
#endif
{
const TArray<TArray<int32>> ConstraintsPerColor = FGraphColoring::ComputeGraphColoringParticlesOrRange(Constraints, InParticles, ParticleOffset, ParticleOffset + ParticleCount);
// Reorder constraints based on color so each array in ConstraintsPerColor contains contiguous elements.
TArray<TVec3<int32>> ReorderedConstraints;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDAnisotropicSpringConstraints.cpp:1260
Scope (from outer to inner):
file
function void FXPBDAnisotropicAxialSpringConstraints::InitColor
function void FXPBDAnisotropicAxialSpringConstraints::Apply
Source code excerpt:
const bool DampingHasWeightMap = DampingRatio.HasWeightMap();
if ((ConstraintsPerColorStartIndex.Num() > 1) && (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount))
{
const int32 ConstraintColorNum = ConstraintsPerColorStartIndex.Num() - 1;
#if INTEL_ISPC
if (bRealTypeCompatibleWithISPC && bChaos_XPBDSpring_ISPC_Enabled)
{
const bool bSingleLambda = Chaos_XPBDSpring_SplitDampingMode == (int32)EXPBDSplitDampingMode::SingleLambda;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDAnisotropicSpringConstraints.cpp:1748
Scope (from outer to inner):
file
function void FXPBDAnisotropicAxialSpringConstraints::InitColor
function void FXPBDAnisotropicAxialSpringConstraints::UpdateLinearSystem
Source code excerpt:
const bool StiffnessBiasHasWeightMap = StiffnessBias.HasWeightMap();
const bool DampingHasWeightMap = DampingRatio.HasWeightMap();
if ((ConstraintsPerColorStartIndex.Num() > 1) && (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount))
{
const int32 ConstraintColorNum = ConstraintsPerColorStartIndex.Num() - 1;
if (!StiffnessHasWeightMap && !StiffnessWeftHasWeightMap && !StiffnessBiasHasWeightMap && !DampingHasWeightMap)
{
const FSolverVec3 ExpStiffnessValue((FSolverReal)StiffnessWeft, (FSolverReal)StiffnessWarp, (FSolverReal)StiffnessBias);
const FSolverReal DampingRatioValue = (FSolverReal)DampingRatio;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDSpringConstraints.cpp:28
Scope (from outer to inner):
file
namespace Chaos::Softs
Source code excerpt:
// @todo(chaos): the parallel threshold (or decision to run parallel) should probably be owned by the solver and passed to the constraint container
int32 Chaos_XPBDSpring_ParallelConstraintCount = 100;
#if !UE_BUILD_SHIPPING
FAutoConsoleVariableRef CVarChaosXPBDSpringParallelConstraintCount(TEXT("p.Chaos.XPBDSpring.ParallelConstraintCount"), Chaos_XPBDSpring_ParallelConstraintCount, TEXT("If we have more constraints than this, use parallel-for in Apply."));
int32 Chaos_XPBDSpring_SplitDampingMode = (int32)EXPBDSplitDampingMode::TwoPassBefore;
FAutoConsoleVariableRef CVarChaosXPBDSpringSplitDamping(TEXT("p.Chaos.XPBDSpring.SplitDamping"), Chaos_XPBDSpring_SplitDampingMode, TEXT("Test xpbd spring split damping mode. 0 = single lambda, 1 = interleaved with damping after (non-ispc only), 2 interleaved with damping before (non-ispc only), 3 = two passes damping after (non-ispc only), 4 = two passes damping before (default)."));
#endif
template<typename SolverParticlesOrRange>
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDSpringConstraints.cpp:41
Scope (from outer to inner):
file
namespace Chaos::Softs
function void FXPBDSpringConstraints::InitColor
Source code excerpt:
// In dev builds we always color so we can tune the system without restarting. See Apply()
#if UE_BUILD_SHIPPING || UE_BUILD_TEST
if (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount)
#endif
{
const TArray<TArray<int32>> ConstraintsPerColor = FGraphColoring::ComputeGraphColoringParticlesOrRange(Constraints, Particles, ParticleOffset, ParticleOffset + ParticleCount);
// Reorder constraints based on color so each array in ConstraintsPerColor contains contiguous elements.
TArray<TVec2<int32>> ReorderedConstraints;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDSpringConstraints.cpp:126
Scope (from outer to inner):
file
namespace Chaos::Softs
function void FXPBDSpringConstraints::Apply
Source code excerpt:
const bool DampingHasWeightMap = DampingRatio.HasWeightMap();
if ((ConstraintsPerColorStartIndex.Num() > 1) && (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount))
{
const int32 ConstraintColorNum = ConstraintsPerColorStartIndex.Num() - 1;
#if INTEL_ISPC
if (bRealTypeCompatibleWithISPC && bChaos_XPBDSpring_ISPC_Enabled)
{
const bool bSingleLambda = Chaos_XPBDSpring_SplitDampingMode == (int32)EXPBDSplitDampingMode::SingleLambda;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/XPBDSpringConstraints.cpp:550
Scope (from outer to inner):
file
namespace Chaos::Softs
function void FXPBDSpringConstraints::UpdateLinearSystem
Source code excerpt:
const bool StiffnessHasWeightMap = Stiffness.HasWeightMap();
const bool DampingHasWeightMap = DampingRatio.HasWeightMap();
if ((ConstraintsPerColorStartIndex.Num() > 1) && (Constraints.Num() > Chaos_XPBDSpring_ParallelConstraintCount))
{
const int32 ConstraintColorNum = ConstraintsPerColorStartIndex.Num() - 1;
if (!StiffnessHasWeightMap && !DampingHasWeightMap)
{
const FSolverReal ExpStiffnessValue = (FSolverReal)Stiffness;
const FSolverReal DampingRatioValue = (FSolverReal)DampingRatio;