From bead7e55bcf6fc1defd337fbe953cb9db9665e41 Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Sun, 19 Feb 2023 19:21:38 +0100 Subject: [PATCH] HUGE performance boost thanks to advice from @fleroviux :heart: --- src/backend/Core.cpp | 27 ++++-------------- src/backend/Core.hpp | 7 +++-- src/backend/core/Interpreter.cpp | 48 ++++++++++++++++++-------------- src/backend/core/Interpreter.hpp | 2 +- src/backend/core/RSP.cpp | 28 +++++++++++++------ src/backend/core/RSP.hpp | 2 +- 6 files changed, 58 insertions(+), 56 deletions(-) diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 39e0c5fd..8219b60e 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -47,29 +47,12 @@ void Core::Run(Window& window, float volumeL, float volumeR) { InterruptRaise(mmio.mi, regs, Interrupt::VI); } - for(;cycles <= mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) { - int cpuCount = CpuStep(*this); - int oldCpuCount = cpuCount; - while(cpuCount--) { - if (!mmio.rsp.spStatus.halt) { - regs.steps++; - if (regs.steps > 2) { - mmio.rsp.steps += 2; - regs.steps -= 3; - } + int cpuCount = CpuStep(*this); + frameCycles += cpuCount; - while (mmio.rsp.steps > 0) { - mmio.rsp.steps--; - mmio.rsp.Step(regs, mem); - } - } - } - - mmio.ai.Step(mem, regs, oldCpuCount, volumeL, volumeR); - scheduler.tick(1, mem, regs); - } - - cycles -= mmio.vi.cyclesPerHalfline; + mmio.rsp.Run(cpuCount, regs, mem); + mmio.ai.Step(mem, regs, cpuCount, volumeL, volumeR); + scheduler.tick(cpuCount, mem, regs); } if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) { diff --git a/src/backend/Core.hpp b/src/backend/Core.hpp index 80b9f6cb..3723494b 100644 --- a/src/backend/Core.hpp +++ b/src/backend/Core.hpp @@ -43,14 +43,15 @@ struct Core { static int CpuStep(Core& core) { switch(core.cpuType) { - case CpuType::Dynarec: return core.cpuDynarec->Step(core.mem); - case CpuType::Interpreter: core.cpuInterp->Step(core.mem); return 1; + case CpuType::Dynarec: + return core.cpuDynarec->Step(core.mem); + case CpuType::Interpreter: + return core.cpuInterp->Run(core.mem); case CpuType::NONE: return 0; } } u32 breakpoint = 0; - int cycles = 0; bool pause = true; bool isPAL = false; diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index f20e91d6..5b8dbfbe 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -21,30 +21,36 @@ inline void CheckCompareInterrupt(MI& mi, Registers& regs) { } } -void Interpreter::Step(Mem& mem) { - CheckCompareInterrupt(mem.mmio.mi, regs); +int Interpreter::Run(Mem& mem) { + MMIO& mmio = mem.mmio; + int count = 0; + for(;count <= mmio.vi.cyclesPerHalfline; count++) { + CheckCompareInterrupt(mem.mmio.mi, regs); - regs.prevDelaySlot = regs.delaySlot; - regs.delaySlot = false; + regs.prevDelaySlot = regs.delaySlot; + regs.delaySlot = false; - u32 paddr = 0; - if(!MapVAddr(regs, LOAD, regs.pc, paddr)) { - HandleTLBException(regs, regs.pc); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, false); - return; + u32 paddr = 0; + if(!MapVAddr(regs, LOAD, regs.pc, paddr)) { + HandleTLBException(regs, regs.pc); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, false); + return count; + } + + u32 instruction = mem.Read32(regs, paddr); + + if(ShouldServiceInterrupt(regs)) { + FireException(regs, ExceptionCode::Interrupt, 0, false); + return count; + } + + regs.oldPC = regs.pc; + regs.pc = regs.nextPC; + regs.nextPC += 4; + + Exec(mem, instruction); } - u32 instruction = mem.Read32(regs, paddr); - - if(ShouldServiceInterrupt(regs)) { - FireException(regs, ExceptionCode::Interrupt, 0, false); - return; - } - - regs.oldPC = regs.pc; - regs.pc = regs.nextPC; - regs.nextPC += 4; - - Exec(mem, instruction); + return count; } } \ No newline at end of file diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 05cd0152..224ff7cc 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -7,7 +7,7 @@ namespace n64 { struct Interpreter { Interpreter() = default; ~Interpreter() = default; - void Step(Mem&); + int Run(Mem&); void Reset() { regs.Reset(); } diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index 54bc2a54..b511e135 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -66,16 +66,28 @@ inline void logRSP(const RSP& rsp, const u32 instr) { } */ -void RSP::Step(Registers& regs, Mem& mem) { - gpr[0] = 0; - u32 instr = Util::ReadAccess(imem, pc & IMEM_DSIZE); - oldPC = pc & 0xFFC; - pc = nextPC & 0xFFC; - nextPC += 4; +void RSP::Run(int cpuCount, Registers& regs, Mem& mem) { + while(cpuCount--) { + if (!spStatus.halt) { + regs.steps++; + if (regs.steps > 2) { + steps += 2; + regs.steps -= 3; + } - Exec(regs, mem, instr); + while (steps > 0) { + steps--; + gpr[0] = 0; + u32 instr = Util::ReadAccess(imem, pc & IMEM_DSIZE); + oldPC = pc & 0xFFC; + pc = nextPC & 0xFFC; + nextPC += 4; - //logRSP(*this, instr); + Exec(regs, mem, instr); + //logRSP(*this, instr); + } + } + } } auto RSP::Read(u32 addr) -> u32{ diff --git a/src/backend/core/RSP.hpp b/src/backend/core/RSP.hpp index 65281ac2..485a02cf 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -113,7 +113,7 @@ struct Registers; struct RSP { RSP(); void Reset(); - void Step(Registers& regs, Mem& mem); + void Run(int, Registers& regs, Mem& mem); auto Read(u32 addr) -> u32; void Write(Mem& mem, Registers& regs, u32 addr, u32 value); void Exec(Registers& regs, Mem& mem, u32 instr);