Skip to content

Commit

Permalink
fix(ootk-multi): improved multithreading algorithm to reduce garbage …
Browse files Browse the repository at this point in the history
…collection and variable cloning
  • Loading branch information
thkruz committed Jan 16, 2021
1 parent 774ec62 commit f9e5d63
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 19 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"lint:test": "eslint test",
"sandbox": "http-server ./",
"test": "jest -c scripts/jest-std.json",
"test:coverage": "jest --coverage -c scripts/jest-std.json",
"test:performance": "node test/performance/timing.test.mjs",
Expand Down
10 changes: 3 additions & 7 deletions sandbox.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
<html>
<head>
<script src="./dist/ootk.js"></script>
<script>
var line1 = "1 00005U 58002B 00179.78495062 .00000023 00000-0 00098-0 0 4753";
var line2 ="2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667";
var satrec = Ootk.Sgp4.createSatrec(line1, line2, "wgs72", "i");
var multi = new Ootk.Multi(8);
multi.propagate([satrec], [0,1,2,3,4,5,6,7,8,9,10]).then((m) => console.log(m))
</script>
<script src="./test/performance/satellite.js"></script>
<script src="./test/performance/performance.js"></script>
</head>
<body></body>
</html>
36 changes: 28 additions & 8 deletions src/ootk-multi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,12 @@ interface SatelliteRecord {
class Multi {
threads = 0;
thread = [];
encoderInst = null;
decoderInst = null;

constructor(threads: number) {
this.encoderInst = new TextEncoder();
this.decoderInst = new TextDecoder();
this.threads = threads;
for (let index = 0; index < this.threads; index++) {
this.thread[index] = new Worker('./dist/ootk-multi.worker.js');
Expand All @@ -163,32 +167,35 @@ class Multi {

public propagate(satrecs: SatelliteRecord[], times: number[]) {
return this._propagate(satrecs, times).then((results) => {
let returnArray = [];
const returnArray = new Float32Array(satrecs.length * times.length * 7);
let offset = 0;
for (let index = 0; index < this.threads; index++) {
returnArray = returnArray.concat(JSON.parse(results[index].data));
const dataArray = new Float32Array(results[index].data);
returnArray.set(dataArray,offset);
offset += dataArray.length;
}
return returnArray;
});
}

private async _propagate(satrecs: SatelliteRecord[], times: number[]): Promise<any> {
const tasks = Multi.chunkArray(satrecs, this.threads);
const tasks = Multi.chunkArray2(satrecs, this.threads);
const results = [];

for (let index = 0; index < this.threads; index++) {
const whichWorker = this.thread[index];
const task = JSON.stringify({ type: 'propagate', tasks: tasks[index], times: times });
results.push(this.createTasks(whichWorker, task));
const taskBuffer = this.encoderInst.encode(JSON.stringify({ type: 'propagate', tasks: tasks[index], times: times })).buffer;
results.push(this.createTasks(whichWorker, taskBuffer));
}

return Promise.all(results).then((data) => data);
}

// eslint-disable-next-line class-methods-use-this
private createTasks(whichWorker: Worker, task: string): Promise<any> {
private createTasks(whichWorker: Worker, taskBuffer): Promise<any> {
return new Promise((resolve, reject) => {
whichWorker.postMessage(task);
whichWorker.onmessage = (m) => {
whichWorker.postMessage(taskBuffer,[taskBuffer]);
whichWorker.onmessage = (m) => {
resolve(m);
// whichWorker.terminate();
};
Expand All @@ -199,6 +206,19 @@ class Multi {
});
}

private static chunkArray2(sourceArr: SatelliteRecord[], chunks: number): SatelliteRecord[][] {
const lengthOfArray = sourceArr.length;
const chunkSize = Math.floor(lengthOfArray / chunks);
const result = [];

let i = 0;
while (i < lengthOfArray) {
result.push(sourceArr.slice(i, (i += chunkSize)));
}

return result;
}

private static chunkArray(sourceArr: SatelliteRecord[], chunks: number): SatelliteRecord[][] {
const lengthOfArray = sourceArr.length;
const result = Array.from(Array(chunks), () => []);
Expand Down
21 changes: 17 additions & 4 deletions src/ootk-multi.worker.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// eslint-disable-next-line no-undef
importScripts('./ootk-sgp4.js');

const decoderInst = new TextDecoder();
const encoderInst = new TextEncoder();

onmessage = function (m) {
const data = JSON.parse(m.data);
const data = JSON.parse(decoderInst.decode(m.data));
switch (data.type) {
case 'propagate':
propagate(data);
Expand All @@ -23,9 +26,19 @@ var propagate = (data) => {
for (let j = 0; j < times.length; j++) {
// eslint-disable-next-line no-undef
const stateVector = Ootk.Sgp4.propagate(satrecs[i], times[j]);
satResults.push({ t: times[j], sv: stateVector });
satResults.push(
times[j],
stateVector.position.x,
stateVector.position.y,
stateVector.position.z,
stateVector.velocity.x,
stateVector.velocity.y,
stateVector.velocity.z,
);
}
allResults.push(satResults);
allResults.push(...satResults);
}
postMessage(JSON.stringify(allResults));

const resultBuffer = new Float32Array(allResults).buffer;
postMessage(resultBuffer, [resultBuffer]);
};

0 comments on commit f9e5d63

Please sign in to comment.