Total Frame drop out, including audio dropout glitching

I seem to be forever plagued by occasional audio drop outs in my patches, I have a patch which plays audio WAV files played from, in the element chat Tebjan suggested to look a stride Scenewindow and open the profiler F3, on the cpu page F5 you can see whether it counts up on the hickup, which it does.

I’ve tried this patch on a couple of computers and it does the same thing, every 1:40 it skips, drops audio for 100ms or so, then carrys on.

I am also getting little audio glitches, little clicks, which I don’t think should be happening either. There is a little tic when the audio loops, but thatts just the start and end of the clip…

I’m running a 3rd gen Focusrite Scarlet USB external sound card, so don’t think it’s that, and seems to happen if I’m not playing audio as well.

I’d like to know if anyone else experiences the same thing with this patch…

Glitchtest2.zip (630.2 KB)

Gave it a go, now using Spreadbuilders. There are still some gen2 collections (maybe due to animating the skia paint?) but a lot less “heavy” and - as far as I can tell - no more audio dropouts.

Glitchtest.7z (378.8 KB)

Just so strange it happens at all… the patch is just a modified version of the spray skia learning patch with an audio track playing…

My main patch I’m running is far more complex with output to DMX pixels, and multitouch input… I’ll apply your method to the other skia elements and see if I can get rid of the drop outs on that one too….

Time for some testing….

If you adjust the particle life time in the original patch to result in similar spreadcounts you will most likely also see gen2 garbage collections.

Roger that, maybe I should switch to stride, and instanced particles… all good learning!

Hej guys, we’re experiencing exactly the same issue that SuperflysiNZ is describing here: a gen2 gc is happening exactly every 100 seconds which causes a framedrop and thereby a nasty visual glitch in the project we’re working on. (Verified with 4.9 and 4.10 stable releases) I’ve been inspecting our whole setup, but couldn’t put my finger on anything specific until I’ve noticed that it also happens in simple help patches like e.g. Scene Graph Basics or Example Spheres with Tails.
Is this expected behaviour? Our patches don’t create or dispose many objects so I’m wondering if there’s anything we could do on our side?

thanks for these reports. we can confirm the gen2s causing framedrops and audio glitches under certain scenarios. while we’re on it, trying to better understand these, a quick thing for you to try is exporting the project. this should ideally get rid of the drops.

Had the same issue last week on a students project. For us exporting the project fixed the gen2 the issue. Gen2 sawtooth waves :-)

Could provide the patch if it helps?

Any updates on this? The certain scenarios leading to this issue seems to include using VL.Stride in general. We have a project next month that export is not really a good option for at all (that also seems to lessen the problem but not eliminate it).

This seems like something of a showstopper!

@SuperflysiNZ might be worth naming the thread a little more generally since it is a total frame drop & not limited to audio. Just a thought if others are searching…

@everyoneishappy Are you saying that the glitches/dropouts persist with an exported version of your project? If so, we probably will need to have a separate look at it / keep a separate discussion. Could be that you run into different issues to what the patch posted here exposes.

@phlegma If your patch is different to one provided here, feel free to post it.

And in general, we’re working on a solution. We’ll report back once those changes are available in the preview builds.

1 Like

@Elias here the patch. Hope it helps.
schuhbidu_dark-update.zip (210.3 KB)

By generating a slightly different target code, we managed to greatly improve the runtime performance when running inside the patch editor. Before these changes our system had to track the live instances in order to hotswap the running program.
With the new system we no longer need to track anything, instead the hotswapping code is kind of interleaved in the target code itself, swapping to a new program is basically just switching one pointer.

The new system will be available in upcoming .4 preview builds (>= 1086) and .5 preview builds (>= 177).

In general we’re very happy with the new design, internally it’s much simpler to handle (less corner cases) and also having to only switch one pointer to do the whole hotswap just feels right. Also the initial patch posted here (Glitchtest2) runs smoothly now. The second patch (Shuhbidu) doesn’t really benefit from these changes, for details see below.

It’s also worth mentioning that the target code of an exported application is NOT affected by these changes. The changes only affect patches running inside the editor.

Here is a comparison running the patches posted above. The first comparison (using dotMemory) shows the live memory usage over a period of around 2 minutes and the second comparison (using dotTrace) shows the time spent in garbage collections.

Glitchtest2

dotMemory

4.10

4.11-preview-1086


Much better and no glitches (was running it for 5 minutes). However when we attach the memory profiler the glitches start appearing again every 100 seconds. Detaching the memory profiler the glitches disappear. It seems the profiler causes some sort of hickup when a larger collection occurs.

dotTrace

4.10

4.11-preview-1086

Using dotTrace we can see that the glitch is indeed caused by a garbage collection. In 4.10 that collection causes all threads to block (= glitch), while in 4.11 it doesn’t (= no glitch).
We can also see that the amount of time the system spends doing garbage collection is much lower (3.8% vs. 13.9%).

Shuhbidu

dotMemory

4.10

4.11-preview-1086

Not really much of a difference. This patch suffers from a different issue, it allocates large objects every frame. These allocations are visualized by the violet graph. An object is considered large if it has more than 85.000 bytes. Large objects are allocated in the large object heap (LOH), which only gets cleaned up by the rather expensive Gen2 collections. Therefor large object allocations every frame should be avoided. This can be achieved by re-using mutable collection types (like MutableList) instead of immutable ones (like Spread).

Now what part of the patch is responsible for the large allocations? That question can easily be answered by looking at it with dotTrace and setting the filters on memory and LOH:

Inside the grid patch we see that 1.500 matrices are created every frame (= 96.000 bytes > 85.000 bytes → large object). This part can be patched more efficiently by re-using a SpreadBuilder instead of the loop’s output splicer. Note though, that the downstream InstancingSpreadComponent currently forces the user to connect a spread, upcoming builds will fix that and will allow to connect any collection type.

In general one can say that the patch shows a weak spot in our current node/loop design. We should seriously consider moving to a mutable output collection type for our loops and also enforce the rule that inputs accept all kinds of collections. So that could be seen as the next chapter in the overall topic of reducing the pressure on the garbage collector.

11 Likes

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.