ValveSoftware / steam-audio

Steam Audio
https://valvesoftware.github.io/steam-audio/
Apache License 2.0
2.2k stars 152 forks source link

[Unity] Perormance optimizations concerning calling mCurrentScene.Commit(); in LateUpdate #281

Closed Kulgann closed 6 months ago

Kulgann commented 8 months ago

Description

During the development of our current game we noticed that the LateUpdate method of SteamAudioManger was producing lag spikes of up to 60ms. See screenshot bellow:

ScreenshotSteamAudioLagSpike

What we did was deep profile and establish that the culprit was the regular call to mCurrentScene.Commit()

What we did

We isolated the call to cs mCurrentScene.Commit() in it's own method CommitScene() inside SteamAudioManager and then called that method in the relevant places of SteamAudioDynamicObject and SteamAudioStaticMesh Additionally a transform.hasChanged was added to SteamAudioDynamicObject so that changes are only committed if the object has moved this frame. After this change we did not notice the introduction of any bugs or discrepancies in how the audio was played, but the lag spikes were gone and LateUpdate now takes between 0.1ms and 0.3ms on average ScreenshotSteamAudioNoLagSpike

lakulish commented 8 months ago

This is a good catch, and overall a good fix, thanks!

However, this solution is not thread-safe. iplSceneCommit should not be called concurrently with any simulation functions. This is why SimulationManager.LateUpdate only calls mCurrentScene.Commit() when the simulation thread is in the WaitSleepJoin state.

I think a simple change would be that instead of creating a SteamAudioManager.CommitScene method that commits the scene right away, create a SteamAudioManager.MarkSceneDirty (or similar) method, which just sets a flag indicating that the next LateUpdate should commit the scene if the simulation thread is in WaitSleepJoin state. This flag would then be cleared after the scene is actually committed. This way, the commit will only happen if a static mesh is added or removed, or if a dynamic object is added, removed, or has its transform updated.

Kulgann commented 6 months ago

Thank you for finishing this and I’m sorry nobody from our side managed to get to it.

lakulish commented 6 months ago

@Kulgann No problem! Thanks for investigating the issue and putting together the initial fix.