From: Chris Duncan Date: Fri, 13 Dec 2024 18:54:56 +0000 (-0800) Subject: Scrap async readPixels. Use perf marks to measure. Revert reverse loop that is actual... X-Git-Url: https://zoso.dev/?a=commitdiff_plain;h=4290f50fa82d5c08737de17451a3fadda08de26d;p=libnemo.git Scrap async readPixels. Use perf marks to measure. Revert reverse loop that is actually negatively affecting performance. Revert canvas size to match original lib for testing. Get rid of redundant function in shader. --- diff --git a/src/lib/workers/pow.ts b/src/lib/workers/pow.ts index 6425937..dfcffae 100644 --- a/src/lib/workers/pow.ts +++ b/src/lib/workers/pow.ts @@ -29,11 +29,49 @@ export class Pow { // Both width and height must be multiple of 256, (one byte) // but do not need to be the same, // matching GPU capabilities is the aim - static webglWidth = 256 * 4 - static webglHeight = 256 * 4 + static webglWidth = 256 * 2 + static webglHeight = 256 * 2 static gl = new OffscreenCanvas(this.webglWidth, this.webglHeight).getContext('webgl2') static work0 = new Uint8Array(4) static work1 = new Uint8Array(4) + static SIGMA82: number[] = [ + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 28, 20, 8, 16, 18, 30, 26, 12, 2, 24, + 0, 4, 22, 14, 10, 6, 22, 16, 24, 0, 10, 4, 30, 26, 20, 28, 6, 12, 14, 2, 18, 8, 14, 18, 6, 2, 26, + 24, 22, 28, 4, 12, 10, 20, 8, 0, 30, 16, 18, 0, 10, 14, 4, 8, 20, 30, 28, 2, 22, 24, 12, 16, 6, + 26, 4, 24, 12, 20, 0, 22, 16, 6, 8, 26, 14, 10, 30, 28, 2, 18, 24, 10, 2, 30, 28, 26, 8, 20, 0, + 14, 12, 6, 18, 4, 16, 22, 26, 22, 14, 28, 24, 2, 6, 18, 10, 0, 30, 8, 16, 12, 4, 20, 12, 30, 28, + 18, 22, 6, 0, 16, 24, 4, 26, 14, 2, 8, 20, 10, 20, 4, 16, 8, 14, 12, 2, 10, 30, 22, 18, 28, 6, 24, + 26, 0, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 28, 20, 8, 16, 18, 30, 26, 12, + 2, 24, 0, 4, 22, 14, 10, 6 + ] + static B2B_G_params: number[] = [] + static { + for (let i = 0; i < 12; i++) { + this.B2B_G_params.push(this.SIGMA82[i * 16 + 0]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 1]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 2]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 3]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 4]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 5]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 6]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 7]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 8]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 9]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 10]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 11]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 12]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 13]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 14]) + this.B2B_G_params.push(this.SIGMA82[i * 16 + 15]) + } + } + + /* + for (i = 0; i<12; i++) { + B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]); + -> + B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1]); + */ static hexify (arr: number[] | Uint8Array): string { let out = '' @@ -43,49 +81,7 @@ export class Pow { return out } - static clientWaitAsync (gl: any, sync: any, flags: any, interval_ms: any): Promise { - return new Promise((resolve, reject) => { - function test () { - const res = gl.clientWaitSync(sync, flags, 0) - if (res === gl.WAIT_FAILED) { - reject() - return - } - if (res === gl.TIMEOUT_EXPIRED) { - setTimeout(test, interval_ms) - return - } - resolve() - } - test() - }) - } - - static async readPixelsAsync (x: any, y: any, w: any, h: any, format: any, type: any, dest: any) { - if (this.gl == null) throw new Error('webgl2_required') - const buf = this.gl.createBuffer() - this.gl.bindBuffer(this.gl.PIXEL_PACK_BUFFER, buf) - this.gl.bufferData(this.gl.PIXEL_PACK_BUFFER, dest.byteLength, this.gl.STREAM_READ) - this.gl.readPixels(x, y, w, h, format, type, 0) - this.gl.bindBuffer(this.gl.PIXEL_PACK_BUFFER, null) - - const sync = this.gl.fenceSync(this.gl.SYNC_GPU_COMMANDS_COMPLETE, 0) - this.gl.flush() - - await this.clientWaitAsync(this.gl, sync, 0, 1) - this.gl.deleteSync(sync) - - this.gl.bindBuffer(this.gl.PIXEL_PACK_BUFFER, buf) - this.gl.getBufferSubData(this.gl.PIXEL_PACK_BUFFER, 0, dest) - this.gl.bindBuffer(this.gl.PIXEL_PACK_BUFFER, null) - - this.gl.deleteBuffer(buf) - return dest - } - - static calculate (hashHex: string, threshold: number | string = '0xFFFFFFF8', callback: (nonce: string | PromiseLike) => any): void { - console.log(`start calculate: ${performance.now()}`) if (typeof threshold === 'number') threshold = '0x' + threshold.toString(16) if (!/^[A-F-a-f0-9]{64}$/.test(hashHex)) throw new Error(`invalid_hash ${hashHex}`) let reverseHex = '' @@ -177,13 +173,13 @@ export class Pow { v[a + 1] = o1; } // Sets v[a,a+1] += v[b,b+1] - void add_uint64 (int a, int b) { - add_uint64(a, v[b], v[b+1]); - } + //void add_uint64 (int a, int b) { + //add_uint64(a, v[b], v[b+1]); + //} // G Mixing function void B2B_G (int a, int b, int c, int d, int ix, int iy) { - add_uint64(a, b); + add_uint64(a, v[b], v[b+1]); add_uint64(a, m[ix], m[ix + 1]); // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits @@ -192,7 +188,7 @@ export class Pow { v[d] = xor1; v[d + 1] = xor0; - add_uint64(c, d); + add_uint64(c, v[d], v[d+1]); // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits xor0 = v[b] ^ v[c]; @@ -200,7 +196,7 @@ export class Pow { v[b] = (xor0 >> 24) ^ (xor1 << 8); v[b + 1] = (xor1 >> 24) ^ (xor0 << 8); - add_uint64(a, b); + add_uint64(a, v[b], v[b+1]); add_uint64(a, m[iy], m[iy + 1]); // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits @@ -209,7 +205,7 @@ export class Pow { v[d] = (xor0 >> 16) ^ (xor1 << 16); v[d + 1] = (xor1 >> 16) ^ (xor0 << 16); - add_uint64(c, d); + add_uint64(c, v[d], v[d+1]); // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits xor0 = v[b] ^ v[c]; @@ -328,10 +324,10 @@ export class Pow { const work1Location = this.gl.getUniformLocation(program, 'u_work1') // Draw output until success or progressCallback says to stop - + const frameTimes: number[] = [] const draw = (): void => { if (this.gl == null) throw new Error('webgl2_required') - const start = performance.now() + performance.mark('start') crypto.getRandomValues(this.work0) crypto.getRandomValues(this.work1) @@ -341,28 +337,30 @@ export class Pow { this.gl.clear(this.gl.COLOR_BUFFER_BIT) this.gl.drawArrays(this.gl.TRIANGLES, 0, 6) const pixels = new Uint8Array(this.gl.drawingBufferWidth * this.gl.drawingBufferHeight * 4) - // this.gl.readPixels(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels) - this.readPixelsAsync(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels) - .then(pixels => { - // Check the pixels for any success - for (let i = pixels.length - 4; i >= 0; i -= 4) { - if (pixels[i] !== 0) { - console.log(`frame time: ${performance.now() - start}`) - const hex = this.hexify(this.work1) + this.hexify([ - pixels[i + 2], - pixels[i + 3], - this.work0[2] ^ (pixels[i] - 1), - this.work0[3] ^ (pixels[i + 1] - 1) - ]) - // Return the work value with the custom bits - typeof callback === 'function' && callback(hex) - return - } - } - console.log(`frame time: ${performance.now() - start}`) - // Nothing found yet, try again - self.requestAnimationFrame(draw) - }) + this.gl.readPixels(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, pixels) + // Check the pixels for any success + for (let i = 0; i < pixels.length; i += 4) { + if (pixels[i] !== 0) { + performance.mark('end') + frameTimes.push(performance.measure('draw', 'start', 'end').duration) + performance.clearMarks() + console.log(`average frame time: ${(frameTimes.reduce((a, b) => a + b)) / frameTimes.length} ms`) + const hex = this.hexify(this.work1) + this.hexify([ + pixels[i + 2], + pixels[i + 3], + this.work0[2] ^ (pixels[i] - 1), + this.work0[3] ^ (pixels[i + 1] - 1) + ]) + // Return the work value with the custom bits + typeof callback === 'function' && callback(hex) + return + } + } + performance.mark('end') + frameTimes.push(performance.measure('draw', 'start', 'end').duration) + performance.clearMarks() + // Nothing found yet, try again + self.requestAnimationFrame(draw) } // Begin generation