r/EmuDev • u/Imaginary_Heat_2235 • 15h ago
NES I put the NES inside a CUDA kernel, one console per thread, and ran 65k of them at once
Built this for a reinforcement learning project (PPO on Super Mario Bros), but the emulator side turned out to be the interesting part, so I figured this sub would care more about that.
One CUDA thread runs one entire console. 6502, PPU, bus, OAM DMA. State is structure-of-arrays indexed by env id, and CPU registers stay in hardware registers for the life of the kernel. 65,536 independent consoles at about 3.3M steps/s on an A100.
- CPU passes the Klaus functional test suite, cycle counts included
- PPU is not cycle accurate. SMB's title screen never advances past the menu because of a timing bug I haven't fixed. I sidestep it by resetting from a save state
- No APU. The registers exist as a byte array, nothing generates sound
- Mapper 0 only
Two results that surprised me:
Opcode-binned dispatch (sorting a warp's threads by opcode before executing) came out 3.2x slower than just letting them diverge. I tested it on instruction streams sampled from 535M profiled SMB executions. A decorrelated warp holds about 20.6 distinct opcodes, and hardware SIMT reconvergence was already sharing fetch and addressing acrossthem. Explicit binning serializes what it was already sharing.
Putting the zero page in shared memory was a 1.9x regression. 256 bytes across 128 threads is 32KB per block, which drops occupancy from 32 warps to 6.
https://github.com/hbofz/NeSLE
Would love help with mappers. MMC1 and MMC3 would open up most of the library.
14
u/Aliryth 8h ago
The rare non-slop post and it's absolutely magnificent.
Well done! What kind of usages do you anticipate for outcomes, or just a cool project for the PPO thing?
I'm interested in learning more!
Also I should put a disclaimer that I'm by far not an anti-AI person, but good lord the "I paid $20 for Claude to make a GameBoy emulator in a single commit" posts are getting rough, extending to other niche programming circles like OS/Kernel dev.
1
u/hurricane_news 4h ago
The rare non-slop post and it's absolutely magnificent.
Well done! What kind of usages do you anticipate for outcomes, or just a cool project for the PPO thing?
I'm interested in learning more!the post itself has a ton of telltale signs of being AI generated
If the project itself is done by OP and not done by an LLM, all good I suppose
4
5
u/StereoRocker 13h ago
I can't help the code, but I can say this is pretty damn cool.
Is the 3.3M steps/sec per instance, or cumulative across all of them? Are you able to translate roughly what FPS you're achieving on each instance?
4
u/Imaginary_Heat_2235 12h ago
Cumulative. Per instance at 65,536 envs it’s ~50 env-steps/s each, frameskip 4, so ~199 NES fps per console (3.3x real time), times 65,536.
Scales down as you go up: 4,096 envs = 304 fps each, 65,536 = 199, 131,072 = 93. And at 1 env the GPU loses to a CPU emulator (0.4x, launch overhead). Overtakes by 8 envs.
Terrible way to run one NES, good way to run 65,536.
-26
u/Even-Serve-3095 13h ago
ew nv*dia-only software, gross
3
u/Imaginary_Heat_2235 12h ago
Believe me, I’m not doing this out of brand loyalty. ROCm PR welcome.
-3
20
u/Far_Outlandishness92 14h ago
Wow, didn't even think this was possible. I am impressed!! A lot!