-
Notifications
You must be signed in to change notification settings - Fork 2
/
hack_demo.js
130 lines (117 loc) · 3.27 KB
/
hack_demo.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Demonstration of new HGWOptions API. Creates 3000 H/G/W workers
// that execute as fast as possible.
// Requires ~5220GB free on home.
/** @param {NS} ns */
function createWorkerScript(ns, wType) {
ns.write(
`/worker/hack_demo_${wType}.js`,
`
/** @param {NS} ns */
export async function main(ns) {
const target = ns.args[0];
const port = ns.getPortHandle(ns.pid);
let now = performance.now();
while (true) {
port.write(now);
await port.nextWrite();
await ns.${wType}(target, { additionalMsec: port.read() });
now = performance.now();
}
}
`.trim(),
"w"
);
}
/** @param {NS} ns */
export async function main(ns) {
const target = "n00dles";
const BATCHES = 1000;
const WORKERS = BATCHES * 3;
const startTime = performance.now();
ns.disableLog("ALL");
ns.tail();
const order = ["hack", "grow", "weaken"];
for (const wType of order) {
createWorkerScript(ns, wType);
}
for (const process of ns.ps()) {
if (process.filename.startsWith("/worker/hack_demo_")) {
ns.kill(process.pid);
}
}
const workers = [];
const ports = [];
ns.atExit(() => {
for (let i = 0; i < workers.length; ++i) ns.kill(workers[i]);
});
// Start a throwaway set of jobs, to compile
for (let j = 0; j < 3; ++j) {
const pid = ns.run(`/worker/hack_demo_${order[j]}.js`, 1, target);
if (!pid) {
throw new Error(`Failed to run starter script #${j}`);
}
workers[j] = pid;
ports[j] = ns.getPortHandle(pid);
}
await ports[2].nextWrite();
for (let j = 0; j < 3; ++j) {
ns.kill(workers[j]);
}
const compileTime = performance.now();
for (let i = 0; i < WORKERS; i += 3) {
for (let j = 0; j < 3; ++j) {
const pid = ns.run(`/worker/hack_demo_${order[j]}.js`, 1, target, i);
if (!pid) {
throw new Error(`Failed to run script #${i + j}`);
}
workers[i + j] = pid;
ports[i + j] = ns.getPortHandle(pid);
}
}
const offset = ns.args[0] ?? 0.1;
const launchedTime = performance.now();
ns.printf(
"Compiled in %.1fms, Launched %d scripts in %.1fms",
compileTime - startTime,
WORKERS,
launchedTime - compileTime
);
let first = true;
while (true) {
const hackTime = ns.getHackTime(target);
const times = [hackTime * 3.0 + offset, hackTime * 0.8 + offset, offset];
const loopStart = performance.now();
if (first === false) {
for (let i = 0; i < WORKERS; i += 3) {
for (let j = 0; j < 3; ++j) {
ports[i + j].write(times[j]);
}
}
}
const loopEnd = performance.now();
await ports[WORKERS - 1].nextWrite();
const loop2Start = performance.now();
const firstTime = ports[0].read();
let last = firstTime;
for (let i = 1; i < WORKERS; ++i) {
const time = ports[i].read();
if (time < last) {
throw new Error(
`Script #${i} with pid ${workers[i]} out-of-order: Ran at ${time} when previous script ran at ${last}`
);
}
last = time;
}
const loop2End = performance.now();
if (!first) {
ns.printf(
"Signaled: %.1fms, Waiting: %.1fms, Running: %.1fms, ReadPort: %.1fms",
loopEnd - loopStart,
loop2Start - loopEnd,
last - firstTime,
loop2End - loop2Start
);
}
first = false;
}
}