TASEmulators / BizHawk

BizHawk is a multi-system emulator written in C#. BizHawk provides nice features for casual gamers such as full screen, and joypad support in addition to full rerecording and debugging tools for all system cores.
http://tasvideos.org/BizHawk.html
Other
2.21k stars 386 forks source link

TASStudio saving asynchronously #2613

Open Aurumaker72 opened 3 years ago

Aurumaker72 commented 3 years ago

Summary

Saving a large TASStudio project completely blocks the UI Thread from responding until saving is finished, meaning no work gets done in those 5+ seconds. This is especially annoying with autosave on. Perhaps the I/O could be done on a separate thread asynchronously.

Repro

  1. Get a large TASStudio project file and open it
  2. CTRL + S
  3. Observe the lag, you cant do anything while it's saving

Host env.

nattthebear commented 3 years ago

We can look at various speedups of course, but the lion's share of the time is probably greenzone saving. If we wanted to async that, we'd need to make a second copy of the greenzone before returning control (so that the main thread could start mutating the greenzone), which might take as much time as saving, and certainly a lot of memory.

adelikat commented 3 years ago

Yes, Almost the entire amount of time is spent saving the greenzone. And making a copy would take the same amount of time, so there is no benefit to asyncing it, unfortunately

vadosnaprimer commented 3 years ago

The easy solution used to be greenzone gaps in saved projects. For example it's safe to have gaps of about 100 frames or more when you save, because when you load it again you can reemulate things. But it will decrease the saving time dramatically.

I haven't precisely looked but whatever the second priority state frequency is, may be used for first priority states when you save. Does my description make sense?

adelikat commented 3 years ago

What i hear you suggesting is to not save the "current" and "gap" buffers, and only save the "recent" and "reserved" buffers

vadosnaprimer commented 3 years ago

Apply the settings of "recent" when saving "current", all the rest being as is. Obviously it shouldn't remove the states that are currently in tasproject's memory, just ignore some of them when saving to disk.

In old tsm it was implemented by only saving every Nth state of the main buffer, user configuring the N.

nattthebear commented 3 years ago

So "thin out" the current states when saving. Might help?

YoshiRulz commented 3 years ago

OP is on 2.4, has the performance improved at all since then?

vadosnaprimer commented 3 years ago

So "thin out" the current states when saving. Might help?

If that doesn't remove them from the project currently in memory. Is that feasible?

nattthebear commented 3 years ago

Anything's possible, the question is how much it saves. Might be nice to start by profiling the various parts of the save to confirm that the time is being spent where you think it is.

zeromus commented 3 years ago

One crazy idea: keep two data structures in memory, call it P and S for primary and secondary. To save: detach S which can then be saved in parallel. Also, any time tastudio doesn't have a fully synchronized S, create one if needed and keep synchronizing it in parallel. If you try to save and S is not fully synchronized, discard S and save P synchronously instead. Of course this is tricky and risky (and irresponsible when we still have basic tas-related desyncing) but now that we understand the requirements better, it should be built into the design of any future implementations

vadosnaprimer commented 3 years ago

Sounds easier to only save every 16th frame from 2 main buffers.

zeromus commented 3 years ago

Sure, sounds way easier. but it sounds like better results to design for the needed capabilities instead of gauging the degree of nuisance and dividing it by 16

Aurumaker72 commented 3 years ago

OP is on 2.4, has the performance improved at all since then?

No

Meerkov commented 3 years ago

And making a copy would take the same amount of time

This doesn't sound right. When the autosave happens, it's hitting disk. When you copy in RAM, it should be much faster. Hitting disk on the UI thread is likely why it's unresponsive.

CasualPokePlayer commented 1 year ago

This should be much better with newer BizHawk versions as greenzone gets compressed down with Zstd, which is much faster than Deflate and offers much better compression ratios, so disk I/O has much less to actually worry about.

If you want it to be even faster, it could be better to just set autosave to Autosave As Backup File, which will omit greenzone. You can check Autosave as Bk2 alongside that if you want it to be even faster (as a bk2 would be extremely fast to save, to the point autosaving would be completely unnoticeable)