94 lines
3.2 KiB
JavaScript
94 lines
3.2 KiB
JavaScript
'use strict';
|
|
|
|
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
|
|
|
|
const ARRAY_SIZE = 15000576;
|
|
const NUM_THREADS = 8; // Reduced from 12 to minimize overhead; adjust to your core count (e.g., 4-16)
|
|
|
|
function getTime() {
|
|
const ns = process.hrtime.bigint();
|
|
return Number(ns) / 1e9; // Returns seconds
|
|
}
|
|
|
|
if (isMainThread) {
|
|
(async () => {
|
|
let start, end;
|
|
|
|
// Time memory allocation
|
|
start = getTime();
|
|
const sabA = new SharedArrayBuffer(ARRAY_SIZE * 4);
|
|
const sabB = new SharedArrayBuffer(ARRAY_SIZE * 4);
|
|
const sabC = new SharedArrayBuffer(ARRAY_SIZE * 4);
|
|
const a = new Float32Array(sabA);
|
|
const b = new Float32Array(sabB);
|
|
const c = new Float32Array(sabC);
|
|
end = getTime();
|
|
const allocTime = end - start;
|
|
|
|
// Time array initialization (single-threaded, like original C)
|
|
start = getTime();
|
|
for (let i = 0; i < ARRAY_SIZE; i++) {
|
|
a[i] = i;
|
|
b[i] = i * 2;
|
|
}
|
|
end = getTime();
|
|
const initTime = end - start;
|
|
|
|
// Create workers for parallel computation
|
|
const chunkSize = Math.floor(ARRAY_SIZE / NUM_THREADS);
|
|
const workerPromises = [];
|
|
|
|
// Time worker creation and execution (only for computation)
|
|
start = getTime();
|
|
for (let t = 0; t < NUM_THREADS; t++) {
|
|
const workerStart = t * chunkSize;
|
|
const workerEnd = (t === NUM_THREADS - 1) ? ARRAY_SIZE : (t + 1) * chunkSize;
|
|
const worker = new Worker(__filename, {
|
|
workerData: {
|
|
start: workerStart,
|
|
end: workerEnd,
|
|
sabA,
|
|
sabB,
|
|
sabC
|
|
}
|
|
});
|
|
workerPromises.push(new Promise((resolve, reject) => {
|
|
worker.on('exit', resolve);
|
|
worker.on('error', reject);
|
|
}));
|
|
}
|
|
|
|
// Wait for workers to finish
|
|
await Promise.all(workerPromises);
|
|
end = getTime();
|
|
const threadTime = end - start;
|
|
|
|
// Print timing results (matching original structure)
|
|
console.log(`Memory allocation time: ${(allocTime * 1000).toFixed(6)} ms`);
|
|
console.log(`Array initialization time: ${(initTime * 1000).toFixed(6)} ms`);
|
|
console.log(`Thread execution time: ${(threadTime * 1000).toFixed(6)} ms`);
|
|
console.log(`Total time: ${((allocTime + initTime + threadTime) * 1000).toFixed(6)} ms`);
|
|
|
|
// Print a sample of the result
|
|
for (let i = 0; i < 10; i++) {
|
|
console.log(`c[${i}] = ${c[i]}`);
|
|
}
|
|
|
|
// No explicit cleanup (garbage collected)
|
|
})();
|
|
} else {
|
|
const { start, end, sabA, sabB, sabC } = workerData;
|
|
const a = new Float32Array(sabA);
|
|
const b = new Float32Array(sabB);
|
|
const c = new Float32Array(sabC);
|
|
|
|
// Parallel computation only
|
|
for (let i = start; i < end; i++) {
|
|
c[i] = a[i] + b[i];
|
|
}
|
|
|
|
// Tip: For extra speed, you could combine init into this loop (if moved from main thread),
|
|
// but that would parallelize init too: a[i] = i; b[i] = i * 2; c[i] = a[i] + b[i];
|
|
|
|
// Worker exits automatically
|
|
} |