From 832a602bedc98a2abf952ce2ebe99c454eb49b21 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Mon, 21 Apr 2025 10:53:48 -0700 Subject: [PATCH] Reuse DataView for reading mapped result data. --- src/lib/gpu/index.ts | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/lib/gpu/index.ts b/src/lib/gpu/index.ts index af6f545..d4c1ba9 100644 --- a/src/lib/gpu/index.ts +++ b/src/lib/gpu/index.ts @@ -21,6 +21,7 @@ export class NanoPowGpu { static #cpuBuffer: GPUBuffer static #uboBuffer: GPUBuffer static #uboView: DataView + static #resultView: DataView static #bindGroupLayout: GPUBindGroupLayout static #searchPipeline: GPUComputePipeline static #validatePipeline: GPUComputePipeline @@ -151,7 +152,7 @@ export class NanoPowGpu { console.table(averages) } - static async #dispatch (pipeline: GPUComputePipeline, seed: bigint, hash: string, difficulty: bigint, passes: number): Promise { + static async #dispatch (pipeline: GPUComputePipeline, seed: bigint, hash: string, difficulty: bigint, passes: number): Promise { if (this.#device == null) throw new Error(`WebGPU device failed to load.`) // Set up uniform buffer object // Note: u32 size is 4, but total alignment must be multiple of 16 @@ -205,20 +206,18 @@ export class NanoPowGpu { this.#device.queue.submit([commandEncoder.finish()]) // Read results back to Javascript and then unmap buffer after reading - let data = null try { await this.#cpuBuffer.mapAsync(GPUMapMode.READ) await this.#device.queue.onSubmittedWorkDone() - data = new DataView(this.#cpuBuffer.getMappedRange().slice(0)) + this.#resultView = new DataView(this.#cpuBuffer.getMappedRange().slice(0)) this.#cpuBuffer.unmap() } catch (err) { console.warn(`Error getting data from GPU. ${err}`) this.#cpuBuffer.unmap() this.reset() } - if (this.#debug) console.log('gpuBuffer data', data) - if (data == null) throw new Error(`Failed to get data from buffer.`) - return data + if (this.#debug) console.log('gpuBuffer data', this.#resultView) + if (this.#resultView == null) throw new Error(`Failed to get data from buffer.`) } /** @@ -281,10 +280,10 @@ export class NanoPowGpu { const random1 = Math.floor(Math.random() * 0xffffffff) const seed = (BigInt(random0) << 32n) | BigInt(random1) if (this.#debug) console.log('seed', seed.toString(16).padStart(16, '0')) - const data = await this.#dispatch(this.#searchPipeline, seed, hash, difficulty, effort) - const found = !!data.getUint32(0) - nonce = data.getBigUint64(8, true) - result = data.getBigUint64(16, true) + await this.#dispatch(this.#searchPipeline, seed, hash, difficulty, effort) + const found = !!this.#resultView.getUint32(0) + nonce = this.#resultView.getBigUint64(8, true) + result = this.#resultView.getBigUint64(16, true) this.#busy = !found times.push(performance.now() - start) } while (this.#busy) @@ -352,9 +351,9 @@ export class NanoPowGpu { const seed = BigInt(`0x${work}`) if (this.#debug) console.log('work', work) - const data = await this.#dispatch(this.#validatePipeline, seed, hash, difficulty, 1) - nonce = data.getBigUint64(8, true) - result = data.getBigUint64(16, true) + await this.#dispatch(this.#validatePipeline, seed, hash, difficulty, 1) + nonce = this.#resultView.getBigUint64(8, true) + result = this.#resultView.getBigUint64(16, true) this.#busy = false if (this.#debug) console.log('nonce', nonce, nonce.toString(16).padStart(16, '0')) if (this.#debug) console.log('result', result, result.toString(16).padStart(16, '0')) -- 2.34.1