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

iR5900: Reset manual protection counters on emulation reset #12259

Merged
merged 1 commit into from
Feb 12, 2025

Conversation

TheLastRar
Copy link
Contributor

Description of Changes

Resets the manual protection counters on emulator reset

Rationale behind Changes

This counters are used to avoid excessive recompilation of blocks that share a page with data see;

// Tweakpoint! 3 is a 'magic' number representing the number of times a counted block
// is re-protected before the recompiler gives up and sets it up as an uncounted (permanent)
// manual block. Higher thresholds result in more recompilations for blocks that share code
// and data on the same page. Side effects of a lower threshold: over extended gameplay
// with several map changes, a game's overall performance could degrade.
// (ideally, perhaps, manual_counter should be reset to 0 every few minutes?)
if (!contains_thread_stack && manual_counter[inpage_ptr >> 12] <= 3)

For some currently unknown reason, the initial value of these counters has an observable impact on TAS playback (at least with Jak X)
As these arrays weren't previously cleared, the sequential playback of the same TAS file will playback differently.

Ideally, we would investigate why this has an effect on TAS playback (especially given that these values are not stored in savestates), but I believe these arrays should be reset regardless.

Suggested Testing Steps

This might impact the performance on the second game launched in a PCSX2 session (or a relaunch of the same game)

For TAS playback testing, the following steps is what I've been testing with
Enable Pause on Start and Disable MTVU
Start a game, start input recording (from boot), then unpause
The second tutorial in Jak X is sensitive to this issue
Once recorded, close and reopen the emulator to get a clean state

Start a game, select the recording to play, then unpause
At the end of the recording, stop it and shutdown emulation
Relaunch the game, reselect the recording and unpause
Observe if any differences occur in playback between the 1st and 2nd run.

@Ziemas
Copy link
Contributor

Ziemas commented Feb 1, 2025

Hmm, interesting.

I guess it makes sense that our JIT might be inherently non-deterministic, because the order in which blocks get recompiled can affect their shape. I'd guess not clearing the manual page tracking results in the page being cleared at a different time which means blocks might be recompiled in a different order.

For example, consider this.

label1:
    nop
    nop
label2:
    nop
    jr $ra

Possible order of operations 1:

  • Jump to label1
    • Recompile a block spanning from label1 to the jr instruction.
  • Jump to label2
    • Recompile a block spanning from label2 to the jr instruction.
  • This results in two overlapping blocks.

Possible order of operations 2:

  • Jump to label2
    • Recompile a block spanning from label2 to the jr instruction.
  • Jump to label1
    • Recompile a block spanning from label1 to label2
    • Link to label2 block by directly jumping to it.
  • This results in two non-overlapping linked blocks.

It's quite possible that this results in different timings or cycle tracking.

At least I think this is what could be going on, I'm not sure i fully understand the JIT.

@kage2051
Copy link

kage2051 commented Feb 4, 2025

This still does not fix the non-determinism when savestates are used though. I guess the content in that array might need storing in savestates, unless there is something else in the JIT for the emulated EE CPU that isn't properly resetted either.

@Ziemas
Copy link
Contributor

Ziemas commented Feb 4, 2025

The JIT starts from a pretty clean state on savestate load, we don't save emitted code or the state of the block cache. So yeah, there are probably the same issues with savestates too.

@F0bes F0bes merged commit 8316228 into PCSX2:master Feb 12, 2025
12 checks passed
@TheLastRar TheLastRar deleted the why-does-this-break-tas branch February 12, 2025 19:16
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.

4 participants