-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Misc sector loading optimizations #3674
Misc sector loading optimizations #3674
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3674 +/- ##
==========================================
- Coverage 71.73% 71.70% -0.03%
==========================================
Files 346 346
Lines 33761 33798 +37
Branches 2652 2653 +1
==========================================
+ Hits 24217 24236 +19
- Misses 9437 9454 +17
- Partials 107 108 +1
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing contribution! Give me a couple days to digest your findings.
Interesting find on the Spinner, I guess an easy fix there would be to add set loading(loadingState: boolean) {
if (this._loading == loadingState) return; <--- Dont do anything if the state is unchanged
this._loading = loadingState;
// snip As I cant see anywhere else this should have a hot-path. Edit I see when orbiting something the spinner style changes from loading to nonloading very frequently, so I guess there is more to this. |
Yeah, the spinner loading state changes whenever |
Head branch was pushed to by a user without write access
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
Type of change
Description 📝
This PR contains optimizations found to reduce the lag spikes associated with sector loading:
CadManager
consume sectors in batches. The slight delay in loading is not noticeable, but the reduction in lag spikes is. I suspect there's two main reasons why this is so effective, but it's hard to be sure:consumeSector
function is called in a simple for-loop, but not when it's called repeatedly using a very tall rxjs call stack. The reason for this is that the CPU-part of sector loading appears much smaller in a performance profile in Chrome.IndexSet.hasIntersectionWith
for maps, and use this insetModelRenderLayers
, some additional performance was gained.MultiBufferBatchingManager
fromgl.STATIC_DRAW
togl.DYNAMIC_DRAW
. Just seemed more inline with the actual usage.Also, the batching of
consumeSectors
meant sectors would be loaded slightly after the progress reporting happened, which broke visual tests. This PR therefore contains a bit of plumbing to fix this.How has this been tested? 🔍
In order to understand what actually made an impact, a benchmark was created by having the camera rotate around a medium sized asset in a deterministic fashion (0.6 rad/s, 30 sec total, continuous sector loading, 5 sec idle before start), while recording the frame-to-frame intervals. Although benchmarking like this is far from a science, it appeared to be fairly consistent as long as the environment (window mode, resolution, dev tools) were kept the same.
The spinner style updating was also found to cause major lag spikes (see benchmark below). This is not fixed in this PR, and should get it's own PR at some point. It is included when doing benchmarking, since disabling it gave much more consistent measurements.
The following breaks down the changes and their performance impact on my setup (Chrome, Ubuntu). All frame-to-frame measurements in ms:
Vanilla
Vanilla + spinner disabled
Vanilla + spinner disabled + sector batching
Vanilla + spinner disabled + sector batching + IndexSet optimization