Skip to content
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

Save states #4908

Merged
merged 138 commits into from Apr 17, 2020
Merged

Save states #4908

merged 138 commits into from Apr 17, 2020

Conversation

hamish-milne
Copy link
Contributor

@hamish-milne hamish-milne commented Aug 30, 2019

Serialization

Saving the state of an entire HLE emulator is challenging to say the least. This is mainly because we have a combination of: large binary blobs, interwoven object graphs, internal pointers, caches and speed hacks, external interfaces, multiple threads, and function callbacks. But, it is possible to do by a) carefully threading serialization code throughout the relevant classes and b) refactoring out any non-serializable constructs.

I'm using boost::serialization because it has a lot of flexibility, has a lot of built-in functionality (for things like STL containers and smart pointers), deals with most things in a sensible way, and is pretty easy to add into an existing codebase.

There are, however, a few things it (and near any other serialization technique) cannot deal with:

References: These are tricky to deal with because they have to come from somewhere - either the 'parent' object (which means said object has to deal with all its 'children'), or global state, or just.. from some other random object. Fun! Fortunately in our case we're largely limited to global refs, which can be patched in using, effectively, a custom constructor for serialization.

Function pointers: Simply put, these cannot be serialized. 'Static' pointers could maybe work if you built up some sort of map to convert to/from, say a string, but lambdas/std::function are impossible because we can't get into the captures and thread the serialization code through them. So we will have to refactor out all persisted function pointer-like constructs. (Mainly WakeupCallback)

Raw pointers: These are similar to references in that we don't know where they come from. They could be internal pointers, objects on the heap, managed by this object or another object, etc. We will need to replace all these with either smart pointers, or some structure that allows us to serialize an internal pointer (MemoryRef and friends).

Other things like derived pointers, circular references, maps, lists and so on are all handled by the library.


This change is Reviewable

@B3n30
Copy link
Contributor

B3n30 commented Aug 30, 2019

From discord:

B3N30 heute um 19:36 Uhr
uff that PR is hugh already... Maybe we (or Hamish ) should split it into smaller PRs. One for just the boost part, and then small PRs for each serialization
that way reviewing is easier and it gets merged faster
Also maybe other people could help you with serializing objects

Hamish heute um 19:37 Uhr
Yeah, it's nowhere near complete yet lol.. I'm maybe 1/4 to 1/3 done
Yeah, that would be fantastic!
A lot of this stuff is simple to do, just time consuming

@wwylele
Copy link
Member

wwylele commented Aug 30, 2019

Suggestion: (de)serialization is usually very unit-testable. You can add some to help yourself test it, and help other review it (so people can spend less time questioning the correctness)

@ChrisNonyminus
Copy link

ChrisNonyminus commented Apr 17, 2020

Regarding the Sims 3 and nintendogs+cats performance issues: it seems that normally, the games run slowly, but for whatever reason, once a savestate is loaded, they run fine.

@Dragios
Copy link
Contributor

Dragios commented Apr 17, 2020

I just tried @ChrisNonyminus suggestion. The Sims 3 becomes even faster than Nightly after loading save state. FPS doubles itself from 81 -> 164 FPS. What kind sorcery is this?!?!?!

@hamish-milne
Copy link
Contributor Author

hamish-milne commented Apr 17, 2020

I just tried @ChrisNonyminus suggestion. The Sims 3 becomes even faster than Nightly after loading save state. FPS doubles itself from 81 -> 164 FPS. What kind sorcery is this?!?!?!

I guess I'm just 😏 that good.

Probably it's the result of some cache being cleared. We've noticed the rasterizer cache is slower the more entries are in it, for instance. I'll investigate

@B3n30
Copy link
Contributor

B3n30 commented Apr 17, 2020

This PR was created on 30 Aug 2019 so it is rotting here since a long time. I'm going to merge it...

@B3n30 B3n30 merged commit c605bb4 into citra-emu:master Apr 17, 2020
1 of 4 checks passed
@Dragios Dragios mentioned this pull request Apr 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet