High/Low level emulation: Difference between revisions

Ahayri (talk | contribs)
Ahayri (talk | contribs)
Line 73: Line 73:
Emulators often include interpreters for CPU cores, executing guest instructions sequentially. Though slower than JITs, interpreters are useful for offering fallback mechanisms, debugging, edge case testing, and platforms without official JIT support (e.g., iOS or WebAssembly environments). [[PPSSPP]] and [[DuckStation]] implements an IR-based interpreter that constructs a lightweight IR without full recompilation, making it fast enough for use on restrictive platforms. Some systems, especially those with self-modifying code (SMC) or tight memory control, require accurate emulation of instruction cache behavior. [[DuckStation]] includes an optional ICache emulation mode that improves internal timing, aligning framerate and performance closer to real [[PlayStation]] hardware.
Emulators often include interpreters for CPU cores, executing guest instructions sequentially. Though slower than JITs, interpreters are useful for offering fallback mechanisms, debugging, edge case testing, and platforms without official JIT support (e.g., iOS or WebAssembly environments). [[PPSSPP]] and [[DuckStation]] implements an IR-based interpreter that constructs a lightweight IR without full recompilation, making it fast enough for use on restrictive platforms. Some systems, especially those with self-modifying code (SMC) or tight memory control, require accurate emulation of instruction cache behavior. [[DuckStation]] includes an optional ICache emulation mode that improves internal timing, aligning framerate and performance closer to real [[PlayStation]] hardware.


* '''[[Dynamic_recompilation|Dynamic Recompilation]]''': (sometimes abbreviated to dynarec or DRC) is a feature of some emulators, where the system may recompile some part of a program during execution. By compiling during execution, the system can tailor the generated code to reflect the program's run-time environment, and potentially produce more efficient code by exploiting information that is not available to a traditional static compiler. Future recompilers may offload tasks to compute shaders, leveraging GPU parallelism. Experimental efforts also explore using machine learning to guide recompilation heuristics or hot path prediction. Emerging trends in this space include the use of intermediate representation (IR) for aggressive ahead-of-time (AOT) optimizations and hybrid JIT-AOT strategies — for instance, compiling hot paths with LLVM and cold paths with a faster, lightweight JIT like Cranelift.
* '''[[Dynamic_recompilation|Dynamic Recompilation]]''': (sometimes abbreviated to dynarec or DRC) is a feature of some emulators, where the system may recompile some part of a program during execution. By compiling during execution, the system can tailor the generated code to reflect the program's run-time environment, and potentially produce more efficient code by exploiting information that is not available to a traditional static compiler. Future recompilers may offload tasks to compute shaders, leveraging GPU parallelism. Experimental efforts also explore using machine learning to guide recompilation heuristics or hot path prediction. Emerging trends in this space include the use of intermediate representation (IR) for aggressive ahead-of-time (AOT) optimizations and hybrid JIT-AOT strategies — for instance, compiling hot paths with LLVM and cold paths with a faster, lightweight JIT like Cranelift. JIT recompilers often maintain persistent caches to avoid redundant translations. These caches may; store translated blocks for re-use within a session, track memory protection and relocation, support serialization across emulator runs (e.g., disk pipeline cache), or use invalidation mechanisms to handle self-modifying code or DMA updates.
** [[PCSX2]] features two prominent JITs: the <code>EE Recompiler</code> for the Emotion Engine (MIPS) and <code>microVU</code> for the Vector Units, both optimized for x86-64 with AVX2 support.
** [[PCSX2]] features two prominent JITs: the <code>EE Recompiler</code> for the Emotion Engine (MIPS) and <code>microVU</code> for the Vector Units, both optimized for x86-64 with AVX2 support.
** [[Citra]] and [[Ryujinx]] use <code>Dynarmic</code>, a fast ARM-to-x86 recompiler with block linking and host code caching.
** [[Citra]] and [[Ryujinx]] use <code>Dynarmic</code>, a fast ARM-to-x86 recompiler with block linking and host code caching.
Line 79: Line 79:
** LLVM is increasingly adopted as a backend to translate emulator IR to optimized native code, offering maintainability and reuse of compiler tooling at the cost of compile-time speed.
** LLVM is increasingly adopted as a backend to translate emulator IR to optimized native code, offering maintainability and reuse of compiler tooling at the cost of compile-time speed.
** New approaches explore <code>AsmJit</code> for fast codegen, <code>MLIR</code> for structured IR optimizations, and <code>libffi</code> or <code>dyncall</code> for cross-platform dynamic call interfaces. On compatible architectures, some emulators (e.g., Yuzu) implement '''Native Code Execution''', bypassing traditional JIT layers for even greater performance and reduced overhead.<ref>{{cite web|url=https://yuzu-mirror.github.io/entry/yuzu-progress-report-nov-2023/#project-nice|title=Yuzu Progress Report Nov 2023|publisher=Yuzu}}</ref>
** New approaches explore <code>AsmJit</code> for fast codegen, <code>MLIR</code> for structured IR optimizations, and <code>libffi</code> or <code>dyncall</code> for cross-platform dynamic call interfaces. On compatible architectures, some emulators (e.g., Yuzu) implement '''Native Code Execution''', bypassing traditional JIT layers for even greater performance and reduced overhead.<ref>{{cite web|url=https://yuzu-mirror.github.io/entry/yuzu-progress-report-nov-2023/#project-nice|title=Yuzu Progress Report Nov 2023|publisher=Yuzu}}</ref>
**'''Recompiler Caches''': JIT recompilers often maintain persistent caches to avoid redundant translations. These caches may; store translated blocks for re-use within a session, track memory protection and relocation, support serialization across emulator runs (e.g., RPCS3’s LLVM cache or Yuzu’s disk pipeline cache), or use invalidation mechanisms to handle self-modifying code or DMA updates, important in systems like the PS2 or PSP.


* '''Fast Memory Access''': Techniques like Fastmem, implemented in [[PCSX2]], Yuzu, and [[Dolphin]], optimize memory operations for significant performance gains by minimizing overhead and improving cache efficiency.<ref>{{cite web|url=https://github.com/PCSX2/pcsx2/pull/5821|title=PCSX2 Pull Request #5821|publisher=GitHub}}</ref><ref>{{cite web|url=https://github.com/PCSX2/pcsx2/pull/7295|title=PCSX2 Pull Request #7295|publisher=GitHub}}</ref><ref>{{cite web|url=https://web.archive.org/web/20240229141516/https://yuzu-emu.org/entry/yuzu-fastmem/#what-is-fastmem|title=What is Fastmem?|publisher=Yuzu}}</ref><ref>{{cite web|url=https://dolphin-emu.org/blog/2016/09/06/booting-the-final-gc-game/|title=Booting the Final GC Game|publisher=Dolphin Emulator}}</ref>
* '''Fast Memory Access''': Techniques like Fastmem, implemented in [[PCSX2]], Yuzu, and [[Dolphin]], optimize memory operations for significant performance gains by minimizing overhead and improving cache efficiency.<ref>{{cite web|url=https://github.com/PCSX2/pcsx2/pull/5821|title=PCSX2 Pull Request #5821|publisher=GitHub}}</ref><ref>{{cite web|url=https://github.com/PCSX2/pcsx2/pull/7295|title=PCSX2 Pull Request #7295|publisher=GitHub}}</ref><ref>{{cite web|url=https://web.archive.org/web/20240229141516/https://yuzu-emu.org/entry/yuzu-fastmem/#what-is-fastmem|title=What is Fastmem?|publisher=Yuzu}}</ref><ref>{{cite web|url=https://dolphin-emu.org/blog/2016/09/06/booting-the-final-gc-game/|title=Booting the Final GC Game|publisher=Dolphin Emulator}}</ref>