Skip to content

Enforces deterministic behavior regarding multi-threading#195

Closed
clementgallet wants to merge 2 commits intoFrodeSolheim:masterfrom
clementgallet:master
Closed

Enforces deterministic behavior regarding multi-threading#195
clementgallet wants to merge 2 commits intoFrodeSolheim:masterfrom
clementgallet:master

Conversation

@clementgallet
Copy link
Copy Markdown

To be able to create tool-assisted speedruns of Amiga games, the emulator needs to run games deterministically. libTAS is a tool to create tool-assisted speedruns for Linux games/programs, and can run fs-uae fine, but there is a non-deterministic behavior in the emulator due to the emulation and the rendering threads running in parallel.

To be more precise:

  • if video_sync option is on, the rendering thread does not wait for a new frame to be available to render. Thus, duplicate frames may happen depending on how fast the threads are running
  • if video_sync option is off, the emulation thread does not wait for the rendering thread to render to start computing the next frame. Because libTAS executes some important code during render calls, which can happen in the middle of a computed frame, it messes up the result of the computed frame.

The present PR reuses the deterministic option to enforce a sequential execution of the rendering and the emulation threads. That would allow us to make TASes of Amiga games.

@vadosnaprimer
Copy link
Copy Markdown

vadosnaprimer commented May 11, 2019

@FrodeSolheim is there a chance for this PR to make it into the next release? The tweaks are minor and should be safe for regular use, but it'd help the TAS scene immensely!

@FrodeSolheim
Copy link
Copy Markdown
Owner

Hi, I think something like this can be included in FS-UAE soon, yes :)

But, I do not want to reuse the deterministic option - that's intended for deterministic emulation, for example netplay. In this case, one should not affect vsync operation, so this needs a separate option.

@clementgallet
Copy link
Copy Markdown
Author

So you would like a specific option for this, right? Something like sequential_execution, without proper documentation?

@FrodeSolheim
Copy link
Copy Markdown
Owner

@clementgallet Yes, I was thinking amount something like 'sequental_execution' (not sure what you meant with "without proper documentation"...).

This pull request can not be included as in FS-UAE due to the underlying fsemu library being rewritten, but I'm still positive to include a sequential execution option.

So I can better understand the need, can you give some more details regarding "Because libTAS executes some important code during render calls, which can happen in the middle of a computed frame, it messes up the result of the computed frame."?

@clementgallet
Copy link
Copy Markdown
Author

Sorry, I probably meant to write "with" instead of "without".

libTAS is a program to add TAS tools to generic games/emulators, so it has to define when a frame starts and ends, without knowledge of the underlying game/emulator code. The definition of a frame that libTAS is using is the time between two screen rendering, which is usually what games/emulators are doing:

while (true) { // game loop
    getInputs();
    runEngine();
    renderScreen();
}

libTAS needs to run some important code between frames, including getting inputs of the next frame from the input file. So, libTAS hooks all rendering functions, and executes the frame boundary code.

It works well in a single-threaded execution, resulting in this:

while (true) { // game loop
    getInputs();
    runEngine();
    renderScreenHooked();
}

renderScreenHooked() {
    updateInputsFromFile();
    realRenderScreen();
}

The problem arises when the game/emulator runs the rendering code in a separate thread, while all the game engine/emulation is done in the main thread (including inputs handling). Inputs are now messed up in two different threads, resulting in undeterministic behavior:

while (true) { // game loop
    getInputs(); // rendering can happen here, resulting in mixed-up inputs 
    runEngine();
    signalThreadToRender();
}

@vadosnaprimer
Copy link
Copy Markdown

vadosnaprimer commented Apr 20, 2020

@FrodeSolheim ping :)

@FrodeSolheim
Copy link
Copy Markdown
Owner

@vadosnaprimer Sorry for not getting back to you; yes, your explanation was very clarifying, so I understand the usecase now :)

As mentioned previously, FS-UAE is being revorked, so this pull request itself is somewhat irrelevant for the future.

I'm positive to including an option for this in FS-UAE (either creating it myself or accepting a pull request). I can also accept this pull request into the fs-uae-3.0 branch in case there will be more 3.0.x releases (not certain) if there is a separate option to enable (deterministic_rendering?)

@FrodeSolheim
Copy link
Copy Markdown
Owner

Closing for now (either implement separate option for FS-UAE 3.0.x, or we'll get back to this with another implementation for FS-UAE 4.x)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants