I’ve been profiling and reading through the chaos physics tick, mainly around StartPhysics and EndPhysics which occur on the game thread and noticed a piece of code that I would expect to cause redundant work when we’re ending a physics frame. Namely after we copy our solver acceleration structure we flush our external acceleration queue, which makes sense, but we do it for all pending spatial data after the acceleration structure’s timestamp or with the same timestamp of the acceleration structure. My understanding is that by definition any pending spatial data with the same time stamp as the acceleration structure should already have been included during the call to FPBDRigidsEvolutionBase::FlushAsyncAccelerationQueue in the physics thread. If I understand correctly, that would mean we’re reupdating the acceleration structure for work that occurred prior to the physics frame beginning when we’re only meant to be including work that occurred since the frame started. Is this a bug or is there some reason that I’m missing that we would need to evaluate operations with the same timestamp as the acceleration structure? The time savings are non-trivial for this change depending on the number of bodies being moved by the game thread (over 0.5ms for us in certain areas) so it would be nice to confirm this is a bug.
void FPBDRigidsEvolutionBase::FlushExternalAccelerationQueue(FAccelerationStructure& Acceleration, FPendingSpatialDataQueue& ExternalQueue)
{
//update structure with any pending operations. Note that we must keep those operations around in case next structure still hasn't consumed them (async mode)
const int32 SyncTimestamp = Acceleration.GetSyncTimestamp();
for (int32 Idx = ExternalQueue.PendingData.Num() - 1; Idx >=0; --Idx)
{
const FPendingSpatialData& SpatialData = ExternalQueue.PendingData[Idx];
// UDN Note: Why is this a >= instead of >?
if(SpatialData.SyncTimestamp >= SyncTimestamp)
{
// ...
}
else
{
//operation was already considered by sim, so remove it
//going in reverse order so PendingData will stay valid
ExternalQueue.Remove(SpatialData.UniqueIdx());
}
}
}