bsnes: Cooperative Threading Serialization and Run-Ahead
I posted a video yesterday explaining and demonstrating the new run-ahead functionality implemented into bsnes.
This turned out to be a very difficult feature to implement on account of bsnes using a cooperative-threaded model of execution that made serialization (save states) non-deterministic.
It took some effort, but I've now implemented a form of deterministic serialization that allows this functionality to work, and I thought it would be useful to write up how this works in the event that any other aspiring emulator developers are considering using cooperative threading but are worried about how to implement save states with them:
Still, it was quite the journey. This seems like an area of computer science that has almost no research behind it, and so I was pretty much on my own in this process.
Not mentioned in the article because it was tied to bsnes specifics, the new run-ahead functionality also required optimizing my emulator's nall/serializer class (with help from Alcaro). It turns out there were some important speed bottlenecks in saving and loading states that were not obvious when you were only saving one state every few seconds, but that become quite apparent when you are both saving and loading states 3,600 times per second.
Anyway, it's really nice to finally have a viable, deterministic method of capturing save states now, and it opens the door to a future bsnes release being able to offer real-time rewind support, rather than just the standard rewind that's in use now (real-time rewind would mean showing every single frame, and playing the audio in reverse order. Sometimes this is referred to as Braid-style rewind.)
But well, that's a task for another day. Please check out the article, and if you're interested in using cooperative threading in an emulator, let me know what you think. Thank you!