};
@group(0) @binding(1) var<storage, read_write> work: WORK;
+/**
+* Shared flag to prevent execution for all workgroup threads based on the
+* atomicLoad() result of a single member thread.
+*/
+var<workgroup> found: bool;
+
/**
* Defined separately from `v0` because the original value is required to
* calculate the digest and compare it to the threshold.
* Calls main with a workgroup size of 64 which has been tested as optimal
*/
@compute @workgroup_size(64)
-fn search(@builtin(global_invocation_id) global_id: vec3<u32>) {
- if (atomicLoad(&work.found) != 0u) { return; }
+fn search(@builtin(global_invocation_id) global_id: vec3<u32>, @builtin(local_invocation_id) local_id: vec3<u32>) {
+ found = (local_id.x == 0u && atomicLoad(&work.found) != 0u);
+ workgroupBarrier();
+ if (found) { return; }
main(global_id);
}
if ((BLAKE2B_IV32_0.y ^ v0.y ^ v8.y) > threshold) {
let wasFound: u32 = atomicExchange(&work.found, 1u);
if (wasFound == 0u) {
- work.nonce = m0;
+ work.nonce = m0;
}
}
return;