Skip to content

New tracing features and performance improvements - #303

Open
RPGHacker wants to merge 12 commits into
nesdev-org:masterfrom
RPGHacker:tracing_improvements
Open

RPGHacker wants to merge 12 commits into
nesdev-org:masterfrom
RPGHacker:tracing_improvements

Conversation

@RPGHacker

Copy link
Copy Markdown

This pull request reworks how tracing functions in Mesen, primarily regarding tracing to a stream (like a file). A large portion of the tracing code has been rewritten and extended, and some new features added that tie to these changes.

Shortly summarized, the following changes were made:

  • Trace data is now buffered and processed in batches at the end of a step or update cycle. This leads to improved cache locality, resulting in better performance.
  • Tracing to a stream (formerly "tracing to a file") now happens on a separate thread, so emulation is no longer impacted by it (as long as memory buffers are still available). This improves peformance even further.
  • There's a new configuration screen for tracing to a stream that allows changing a bunch of settings that were previously hard-coded. It also adds some entirely new settings, including new log targets. All the new settings are detailed below.
grafik

The following settings are now available for tracing:

  • In addition to tracing to a file, you can now trace to a network socket (using Mesen's existing TCP socket implementation).
  • You can specify different formats and compression types for tracing.
    • The availability of these formats depends on the current system and CPU being emulated.
    • Right now, the main SNES CPU (and by extension the SA-1) is the only thing offering any additional formats. It supports the special binary format used by DiztinGUIsh, making it possible to disassemble a SNES ROM from live gameplay in Mesen.
  • Whether to flush trace data in batches, and the size & amount of these batches, can now be configured.
  • The automatic PC prefix on traced lines is now optional and can be disabled.
  • Tracing can be configured to only trace instructions when they are executed with a unique CPU state permutation. This greatly reduces the amount of traced data and improves performance drastically. Very useful for disassembling ROMs, where you typically only care about what unique CPU flags and registers an instruction is called with, not about every single instance of that instruction being executed.
    • However, this feature once again is only available for supported systems and CPUs, which currently is only the main SNES CPU.
    • It should be easy to add support to all the other systems and CPUs as well, as long as their combined relevant CPU state is small enough to fit into a few bytes of memory (the SNES' implementation uses a single uint64_t, for example).
  • Settings for tracing are now saved in Mesen's configuration. So, for example, the target file for logging no longer needs to be selected every time you want to start logging - it's prefilled with the last file path used for logging.

Regarding the aformentioned performance improvements, I observed the following (non-scientific) benchmarks on my own system (decent hardware bought in 2024 with an NVMe SSD as the "log to file" target) running a Terranigma (J) ROM.

Before my changes, I roughly achieved around 55 FPS in Mesen while file logging was active, so not quite the 60 FPS required for smooth gameplay. After my changes (with uncapped framerate), that number has now almost doubled to around 100 FPS. This is for the default case when the raw text format is used and none of the further optimizations are enabled in the settings.

Logging to a network socket might be even faster than that, but there doesn't really exist a good test case for this yet. I can only test this via DiztinGUIsh's live connection feature, which requires Mesen to use its special binary format. This typically sends much less data than using the raw text format and thus is always bound to be faster, anyways.

+ Added partial support for Diztinguish's specifc binary format, which allows hooking Mesen up to Diztinguish for live disassembling
The AddRow() function now only stores the current state, and the tracing is done all at once at the end of the frame. This makes it possible to use resources more efficiently, possibly also reduces the amount of cache misses. In my tests, "log to file" saw a performance increase of roughly 50%, with "log to socket" seeing an increase of up to 200%.
"Trace to file" and "trace to network socket" will, in the future, share some common implementation code. There's now a settings dialog for configuring both fo them, and the settings are stored in Mesen's user settings.
Also made sure some of the new settings actually do something now.
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.

1 participant