p.MaxDirtyElements
p.MaxDirtyElements
#Overview
name: p.MaxDirtyElements
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
The max number of dirty elements. This forces a flush which is very expensive
It is referenced in 5
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of p.MaxDirtyElements is to control the maximum number of dirty elements in the Chaos physics engine’s bounding volume system. This setting is primarily used in the physics simulation and collision detection systems of Unreal Engine 5.
The Chaos physics engine, which is part of Unreal Engine’s experimental features, relies on this setting variable. Specifically, it’s used in the bounding volume and AABB (Axis-Aligned Bounding Box) tree implementations within the Chaos namespace.
The value of this variable is set through a console variable (CVAR) named “p.MaxDirtyElements”. It’s initialized differently depending on whether the code is compiled for the editor or for a shipping build:
- In the editor: MaxDirtyElements = MAX_int32 (maximum value for a 32-bit integer)
- In shipping builds: MaxDirtyElements = 10000
The associated variable MaxDirtyElements interacts directly with p.MaxDirtyElements, as they share the same value. This variable is used in the actual code logic, while p.MaxDirtyElements serves as the console-accessible setting.
Developers must be aware that this variable affects performance significantly. When the number of dirty elements exceeds MaxDirtyElements, it forces a tree rebuild, which is described as “very expensive” in the comments.
Best practices when using this variable include:
- Monitor the number of dirty elements in your physics simulations to ensure it doesn’t frequently exceed the set limit.
- Adjust the value based on your specific use case and performance requirements. A higher value may improve performance by reducing tree rebuilds but could lead to increased memory usage.
- Use different values for editor and shipping builds, as the default configuration suggests.
- Be cautious when modifying this value, as it can have significant performance implications.
Regarding the associated variable MaxDirtyElements:
The purpose of MaxDirtyElements is to store the actual maximum number of dirty elements allowed before forcing a tree rebuild in the Chaos physics engine’s bounding volume system.
It’s used directly in the TAABBTree class, which is part of the spatial acceleration structures in the Chaos physics engine. The variable is checked in the UpdateElement function to determine if a tree rebuild is necessary.
MaxDirtyElements is also used in performance logging and analytics, as seen in the QueryImp function where it’s used with PHYSICS_CSV_CUSTOM_VERY_EXPENSIVE macro.
Developers should be aware that this variable directly impacts the performance and behavior of the physics engine, particularly in collision detection and spatial queries. Changing its value can affect both performance and simulation accuracy.
Best practices for MaxDirtyElements align with those for p.MaxDirtyElements, as they are essentially the same setting exposed in different ways.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/BoundingVolume.cpp:22
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
FAutoConsoleVariableRef CVarMaxDirtyElements(
TEXT("p.MaxDirtyElements"),
MaxDirtyElements,
TEXT("The max number of dirty elements. This forces a flush which is very expensive"));
template class CHAOS_API Chaos::TBoundingVolume<int32, FReal, 3>;
template class CHAOS_API Chaos::TBoundingVolume<FAccelerationStructureHandle, FReal, 3>;
}
#Associated Variable and Callsites
This variable is associated with another variable named MaxDirtyElements
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/BoundingVolume.cpp:16
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
{
#if WITH_EDITOR
CHAOS_API int32 MaxDirtyElements = MAX_int32;
#else
CHAOS_API int32 MaxDirtyElements = 10000;
#endif
FAutoConsoleVariableRef CVarMaxDirtyElements(
TEXT("p.MaxDirtyElements"),
MaxDirtyElements,
TEXT("The max number of dirty elements. This forces a flush which is very expensive"));
template class CHAOS_API Chaos::TBoundingVolume<int32, FReal, 3>;
template class CHAOS_API Chaos::TBoundingVolume<FAccelerationStructureHandle, FReal, 3>;
}
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Public/Chaos/AABBTree.h:726
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
}
extern CHAOS_API int32 MaxDirtyElements;
struct DirtyGridHashEntry
{
DirtyGridHashEntry()
{
Index = 0;
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Public/Chaos/AABBTree.h:2059
Scope (from outer to inner):
file
namespace Chaos
class class TAABBTree final : public ISpatialAcceleration<TPayloadType, T, 3>
function virtual bool UpdateElement
Source code excerpt:
}
if(!DirtyElementTree && !bDynamicTree && DirtyElements.Num() > MaxDirtyElements)
{
UE_LOG(LogChaos, Verbose, TEXT("Bounding volume exceeded maximum dirty elements (%d dirty of max %d) and is forcing a tree rebuild."), DirtyElements.Num(), MaxDirtyElements);
ReoptimizeTree();
}
bModifyingTreeMultiThreadingFastCheck = false;
return bElementExisted;
}
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Public/Chaos/AABBTree.h:2815
Scope (from outer to inner):
file
namespace Chaos
class class TAABBTree final : public ISpatialAcceleration<TPayloadType, T, 3>
function bool QueryImp
Source code excerpt:
bool QueryImp(const FVec3& RESTRICT Start, TQueryFastData& CurData, const FVec3& QueryHalfExtents, const FAABB3& QueryBounds, SQVisitor& Visitor, const FVec3& Dir, const FVec3& InvDir, const bool bParallel[3]) const
{
PHYSICS_CSV_CUSTOM_VERY_EXPENSIVE(PhysicsCounters, MaxDirtyElements, DirtyElements.Num(), ECsvCustomStatOp::Max);
PHYSICS_CSV_CUSTOM_VERY_EXPENSIVE(PhysicsCounters, MaxNumLeaves, Leaves.Num(), ECsvCustomStatOp::Max);
PHYSICS_CSV_SCOPED_VERY_EXPENSIVE(PhysicsVerbose, QueryImp);
//QUICK_SCOPE_CYCLE_COUNTER(AABBTreeQueryImp);
#if !WITH_EDITOR
//CSV_SCOPED_TIMING_STAT(ChaosPhysicsTimers, AABBTreeQuery)
#endif