raise concurrency cap for multi-cpu systems

This commit is contained in:
Stewart Allen 2026-03-04 21:28:32 -05:00
commit 2f1c57e0ae
4 changed files with 34 additions and 19 deletions

View file

@ -41,6 +41,7 @@ export async function slice(points, options = {}) {
zSum = 0.0, // sanity check that points enclose non-zere volume
buckets = [], // banded/grouped faces to speed up slice/search
overlapMax = options.overlap || 0.75,
bucketMin = options.bucketMin ?? 1,
bucketMax = options.bucketMax || 100,
onupdate = options.onupdate || function() {},
sliceFn = dval(options.slicer, sliceZ),
@ -138,7 +139,7 @@ export async function slice(points, options = {}) {
let zSpan = zMax - zMin;
let zSpanAvg = zSum / points.length;
let bucketCount = options.bucket !== false ?
Math.min(bucketMax, Math.max(1, Math.floor(zSpan / zSpanAvg))) : 1;
Math.min(bucketMax, Math.max(bucketMin, Math.floor(zSpan / zSpanAvg))) : 1;
zScale = 1 / (zMax / bucketCount);
@ -211,7 +212,6 @@ export async function slice(points, options = {}) {
let count = 0;
let opt = { ...options, zMin, zMax, zIndexes };
let ps = [];
for (let i = 0, l = buckets.length; i < l; i++) {
let bucket = buckets[i];
let { points, slices } = bucket;

View file

@ -318,6 +318,10 @@ export function sliceOne(settings, widget, onupdate, ondone) {
}
}
if (isConcurrent) {
minions.setPoints(points);
}
// create Slice objects for specified list of Z heights
// zGen() produces the list (or empty for slicer auto-detected)
slice(points, {
@ -326,6 +330,7 @@ export function sliceOne(settings, widget, onupdate, ondone) {
xray: process.xray,
zMin: bounds.min.z,
zMax: bounds.max.z - zCut,
bucketMin: minions.concurrent * 5,
union: controller.healMesh,
indices: process.indices || process.xray,
useAssembly,
@ -351,6 +356,9 @@ export function sliceOne(settings, widget, onupdate, ondone) {
})
.then(decodeSlices)
.then(processSlices)
.then(() => {
minions.setPoints([]);
})
.then(ondone);
// z index generator (bottom up)

View file

@ -154,14 +154,11 @@ const funcs = self.minion = {
sliceZ(data, seq) {
debug('minion.sliceZ', { data, seq });
let { z, points, options } = data;
let i = 0, p = 0, realp = new Array(points.length / 3);
while (i < points.length) {
realp[p++] = newPoint(points[i++], points[i++], points[i++]).round(3);
}
let { z, options } = data;
let { points } = cache;
let state = { zero: [] };
let output = [];
sliceZ(z, realp, {
sliceZ(z, points, {
...options,
each(out) { output.push(out) }
}).then(() => {
@ -173,9 +170,17 @@ const funcs = self.minion = {
});
},
setPoints(data, seq) {
let { points } = data;
let i = 0, p = 0, realp = new Array(points.length / 3);
while (i < points.length) {
realp[p++] = newPoint(points[i++], points[i++], points[i++]).round(3);
}
cache.points = realp;
},
putCache(msg) {
const { key, data } = msg;
// log({ minion_putCache: key, data });
if (data) {
cache[key] = data;
} else {

View file

@ -39,7 +39,7 @@ let drivers = {
WJET
},
ccvalue = self.navigator ? self.navigator.hardwareConcurrency || 0 : 0,
concurrent = Math.min(4, self.Worker && ccvalue > 3 ? ccvalue - 1 : 0),
concurrent = Math.round(Math.max(4, self.Worker && ccvalue > 3 ? ccvalue * 0.75 : 0)),
current = {
print: null,
snap: null,
@ -174,6 +174,16 @@ const minwork = {
}
},
setPoints(points) {
let i = 0, floatP = new Float32Array(points.length * 3);
for (let p of points) {
floatP[i++] = p.x;
floatP[i++] = p.y;
floatP[i++] = p.z;
}
minwork.broadcast("setPoints", { points: floatP });
},
// added functions (should be namespaced)
subtract({ a, b, outA, outB, z, area, wasm }) {
@ -285,17 +295,9 @@ const minwork = {
reject("concurrent slice unavaiable");
}
let { each } = options;
// todo use shared array buffer?
let i = 0, floatP = new Float32Array(points.length * 3);
for (let p of points) {
floatP[i++] = p.x;
floatP[i++] = p.y;
floatP[i++] = p.z;
}
minwork.queue({
cmd: "sliceZ",
z,
points: floatP,
options: codec.toCodable(options)
}, data => {
let recs = codec.decode(data.output);
@ -305,7 +307,7 @@ const minwork = {
}
}
resolve(recs);
}, [ floatP.buffer ]);
});
});
},
};