From 6e3da3c333c70acd6a8a9e88c9ee1502872dc72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com> Date: Tue, 1 Nov 2022 10:36:19 +0000 Subject: [PATCH] refactor: benchmark running structure --- examples/web/index.ts | 46 +++++++++++++++++--------------------- examples/web/react/app.tsx | 46 ++++++++++++++++++++++++++++---------- src/cpu.rs | 2 +- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/examples/web/index.ts b/examples/web/index.ts index b3df5cfc..bc44e844 100644 --- a/examples/web/index.ts +++ b/examples/web/index.ts @@ -361,32 +361,6 @@ class GameboyEmulator extends Observable implements Emulator { } registerButtons() { - const buttonBenchmark = document.getElementById("button-benchmark")!; - buttonBenchmark.addEventListener("click", async () => { - buttonBenchmark.classList.add("enabled"); - this.pause(); - try { - const initial = Date.now(); - const count = 500000000; - for (let i = 0; i < count; i++) { - this.gameBoy!.clock(); - } - const delta = (Date.now() - initial) / 1000; - const frequency_mhz = count / delta / 1000 / 1000; - this.trigger("message", { - text: `Took ${delta.toFixed( - 2 - )} seconds to run ${count} ticks (${frequency_mhz.toFixed( - 2 - )} Mhz)!`, - timeout: 7500 - }); - } finally { - this.resume(); - buttonBenchmark.classList.remove("enabled"); - } - }); - const buttonDebug = document.getElementById("button-debug")!; buttonDebug.addEventListener("click", () => { const sectionDebug = document.getElementById("section-debug")!; @@ -567,6 +541,26 @@ class GameboyEmulator extends Observable implements Emulator { this.boot({ engine: null }); } + benchmark() { + this.pause(); + try { + const initial = Date.now(); + const count = 500000000; + for (let i = 0; i < count; i++) { + this.gameBoy!.clock(); + } + const delta = (Date.now() - initial) / 1000; + const frequency_mhz = count / delta / 1000 / 1000; + return { + delta: delta, + count: count, + frequency_mhz: frequency_mhz + }; + } finally { + this.resume(); + } + } + async fetchRom(romPath: string): Promise<[string, Uint8Array]> { // extracts the name of the ROM from the provided // path by splitting its structure diff --git a/examples/web/react/app.tsx b/examples/web/react/app.tsx index 21fd1c2e..e37d6400 100644 --- a/examples/web/react/app.tsx +++ b/examples/web/react/app.tsx @@ -58,6 +58,12 @@ export type RomInfo = { extra?: Record<string, string | undefined>; }; +export type BenchmarkResult = { + delta: number; + count: number; + frequency_mhz: number; +}; + export interface ObservableI { bind(event: string, callback: Callback<this>): void; trigger(event: string): void; @@ -138,11 +144,20 @@ export interface Emulator extends ObservableI { * Returns the current logic framerate of the running * emulator. * - * @return The current logic framerate of the running + * @returns The current logic framerate of the running * emulator. */ getFramerate(): number; + /** + * Boot (or reboots) the emulator according to the provided + * set of options. + * + * @param options The options that are going to be used for + * the booting operation of the emulator. + */ + boot(options: any): void; + /** * Toggle the running state of the emulator between paused * and running, prevents consumers from the need to access @@ -160,13 +175,12 @@ export interface Emulator extends ObservableI { reset(): void; /** - * Boot (or reboots) the emulator according to the provided - * set of options. + * Runs a benchmark operation in the emulator, effectively + * measuring the performance of it. * - * @param options The options that are going to be used for - * the booting operation of the emulator. + * @returns The result metrics from the benchmark run. */ - boot(options: any): void; + benchmark(): BenchmarkResult; } /** @@ -274,9 +288,12 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => { const onFile = async (file: File) => { // @todo must make this more flexible and not just - // Game Boy only + // Game Boy only (using the emulator interface) if (!file.name.endsWith(".gb")) { - showToast("This is probably not a Game Boy ROM file!", true); + showToast( + `This is probably not a ${emulator.getDevice()} ROM file!`, + true + ); return; } @@ -316,11 +333,16 @@ export const App: FC<AppProps> = ({ emulator, backgrounds = ["264653"] }) => { "Are you sure you want to start a benchmark?\nThe benchmark is considered an expensive operation!", "Confirm" ); + if (!result) return; + const { delta, count, frequency_mhz } = emulator.benchmark(); await showToast( - result - ? "Will run the benchmark as fast as possible" - : "Will not run the benchmark", - !result + `Took ${delta.toFixed( + 2 + )} seconds to run ${count} ticks (${frequency_mhz.toFixed( + 2 + )} Mhz)!`, + undefined, + 7500 ); }; const onFullscreenClick = () => { diff --git a/src/cpu.rs b/src/cpu.rs index b6b0a32f..8acb6c0c 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -112,7 +112,7 @@ impl Cpu { } // @todo this is so bad, need to improve this by an order - // of magnitude + // of magnitude, to be able to have better performance if self.halted { if ((self.mmu.ie & 0x01 == 0x01) && self.mmu.ppu().int_vblank()) || ((self.mmu.ie & 0x02 == 0x02) && self.mmu.ppu().int_stat()) -- GitLab