]> zoso.dev Git - nano-pow.git/commitdiff
Reuse DataView for reading mapped result data.
authorChris Duncan <chris@zoso.dev>
Mon, 21 Apr 2025 17:53:48 +0000 (10:53 -0700)
committerChris Duncan <chris@zoso.dev>
Mon, 21 Apr 2025 17:53:48 +0000 (10:53 -0700)
src/lib/gpu/index.ts

index af6f54548e869a70312e89cef6304af55a281468..d4c1ba90201b927d466f22108047c7de8f16bec8 100644 (file)
@@ -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<DataView> {
+       static async #dispatch (pipeline: GPUComputePipeline, seed: bigint, hash: string, difficulty: bigint, passes: number): Promise<void> {
                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'))