This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.
Main Loop Optimization and Final Checks
Summary
This step completes the optimization of the main loop by identifying and eliminating costly operations that caused variable time between frames (30-150ms). Critical optimizations were applied: disabling logs in the critical loop, optimizing palette verification, moving imports to the beginning of the file, and disabling the GPS monitor. Analysis and verification documents were generated, and all pending verification documents (visual, compatibility, controls) and the status of the strategic plan were updated.
The optimizations applied should improve the FPS from 6-32 variable FPS to 50-60 stable FPS. Manual verification is required to confirm improvements.
Hardware Concept
The main loop of an emulator is critical to performance. Each frame must be completed in~16.67msto maintain 60 FPS. The total time of a frame includes:
- CPU/PPU emulation: Execution of instructions and rendering of scanlines
- Graphic rendering: Converting framebuffer to pixels on screen
- Synchronization: FPS control and event handling
- Loop Overhead: Auxiliary operations (logs, verifications, etc.)
If the render time is low (~3.5ms) but the time between frames is high (30-150ms), the problem is in theloop overhead, not in emulation or rendering. Operations such as I/O (logs), unnecessary checks, or imports within the loop can cause significant pauses.
Fountain:Pan Docs - System Clock, Timing, Frame Rate, LCD Timing
Implementation
Main Loop Analysis
The method was analyzedrun()insrc/viboy.py(lines 694-1334) identifying the following expensive operations:
- Frequent logs(lines 870, 910, 1061): Executed every 60 frames, causing expensive I/O
- Pallet check(lines 784-786): Executes every frame, accessing memory unnecessarily
- Imports inside the loop(lines 877, 911):
import pygameandimport timeinside the loop - Full GPS Monitor(lines 1061-1174): Read many registers and calculate checksums every second
The complete analysis was documented inANALYSIS_LOOP_MAIN_STEP_0317.md.
Applied Optimizations
1. Logs Disabled by Default
A flag was introducedENABLE_DEBUG_LOGS = Falsewhich controls all the logs of the critical loop:
- FPS-LIMITER logs (line 870)
- FPS-DIAG logs (line 910)
- SYNC-CHECK logs (line 906)
The logs are only executed ifENABLE_DEBUG_LOGS = True, allowing them to be activated for debugging when necessary.
2. Optimized Palette Verification
The paddle check (BGP == 0) was moved out of the main loop and runs only once at startup:
# Before: It was executed every frame
if self._mmu.read(0xFF47) == 0:
self._mmu.write(0xFF47, 0xE4)
# After: Runs only once at startup
palette_checked = False
if self._use_cpp and self._mmu is not None:
if self._mmu.read(0xFF47) == 0:
self._mmu.write(0xFF47, 0xE4)
palette_checked = True
3. Imports Moved to Home
The imports ofpygameandtimeThey were moved to the beginning of the file (lines 32-35) to avoid imports inside the loop, although Python caches them, it is better practice.
4. GPS Monitor Disabled
The full GPS monitor (which reads many logs and calculates VRAM checksums) was disabled by default, running only ifENABLE_DEBUG_LOGS = True.
Modified Files
src/viboy.py: Main loop optimizations (lines ~32-35, ~777-793, ~869-917, ~1070)
Generated Documents
ANALYSIS_LOOP_MAIN_STEP_0317.md: Complete analysis of the main loop with costly operations identifiedVERIFICATION_FPS_OPTIMIZATIONS_STEP_0317.md: FPS improvements verification instructions
Updated Documents
VERIFICATION_RENDERIZED_STEP_0312.md: Updated with information from Step 0317COMPATIBILITY_GB_GBC_STEP_0315.md: Updated with information from Step 0317VERIFICATION_CONTROLES_STEP_0315.md: Updated with information from Step 0317STATUS_STRATEGIC_PLAN_STEP_0315.md: Updated with progress from Step 0317
Affected Files
src/viboy.py- Main loop optimizations (logs, palette verification, imports, GPS monitor)ANALYSIS_LOOP_MAIN_STEP_0317.md- Full main loop analysis (new)VERIFICATION_FPS_OPTIMIZATIONS_STEP_0317.md- Verification instructions (new)VERIFICATION_RENDERIZED_STEP_0312.md- Updated with information from Step 0317COMPATIBILITY_GB_GBC_STEP_0315.md- Updated with information from Step 0317VERIFICATION_CONTROLES_STEP_0315.md- Updated with information from Step 0317STATUS_STRATEGIC_PLAN_STEP_0315.md- Updated with progress from Step 0317
Tests and Verification
The optimizations were validated by:
- Static code analysis: Review of the main loop identifying costly operations
- Analysis documentation:
ANALYSIS_LOOP_MAIN_STEP_0317.mdwith identified costly operations and recommendations - Build Verification: C++ modules recompiled successfully
- Manual verification pending: It is required to run the emulator and verify FPS improvements (instructions in
VERIFICATION_FPS_OPTIMIZATIONS_STEP_0317.md)
Expected FPS after optimizations: 50-60 FPS stable (upgraded from 6-32 FPS variable)
C++ Compiled Module Validation: The C++ modules were successfully recompiled without errors.
Sources consulted
- Bread Docs:System Clock, Timing, Frame Rate, LCD Timing
- Previous analysis: Step 0316 - Log Analysis and Final Optimizations
Educational Integrity
What I Understand Now
- Main loop overhead: Auxiliary operations (logs, checks) can cause significant pauses even if emulation and rendering are fast
- I/O is expensive: Logs (print, logger) cause significant overhead when executed frequently in the critical loop
- Unnecessary checks: Checking conditions in each frame when it is only needed once at the beginning is inefficient
- debug flag: Using flags to control logs and monitors allows you to activate them only when necessary for debugging
What remains to be confirmed
- Real FPS improvement: Manual verification required by running the emulator to confirm that the optimizations improve the FPS from 6-32 FPS to 50-60 FPS
- FPS Stability: Verify that FPS is more stable after optimizations
- No regressions: Confirm that optimizations did not introduce issues (rendering, compatibility, controls)
Hypotheses and Assumptions
It is assumed that the optimizations applied (disable logs, optimize palette verification, move imports) will significantly improve the FPS. If the improvements are not sufficient, it may be necessary to optimize the framebuffer copy or investigate other costly operations with more detailed profiling.
Next Steps
- [ ] Check FPS improvements manually by running the emulator (instructions on
VERIFICATION_FPS_OPTIMIZATIONS_STEP_0317.md) - [ ] Final visual verification (document updated in Step 0317)
- [ ] GB/GBC compatibility check (document updated in Step 0317)
- [ ] Verification of controls (document updated in Step 0317)
- [ ] If the optimizations are not enough, consider optimizing the framebuffer copy or more detailed profiling
- [ ] Continue with Phase 3 of the strategic plan (Controls and Gameplay) once verifications are completed