]> zoso.dev Git - libnemo.git/commitdiff
Scrap async readPixels. Use perf marks to measure. Revert reverse loop that is actual...
authorChris Duncan <chris@zoso.dev>
Fri, 13 Dec 2024 18:54:56 +0000 (10:54 -0800)
committerChris Duncan <chris@zoso.dev>
Fri, 13 Dec 2024 18:54:56 +0000 (10:54 -0800)
src/lib/workers/pow.ts

index 6425937e7291b50d10d9d0789de281efbcaa763d..dfcffaee061220bc042b2d7b3e927d88cbca3726 100644 (file)
@@ -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<void> {
-               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<string>) => 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