mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 22:52:29 +01:00
BUGFIX: Fix rounding issues due to ramOverride edge cases (#1339)
*All* RAM calculations must take place in units of hundredths-of-a-GB in order for there not to be issues. Also adds slightly more verbose logging when the dynamic RAM check fails.
This commit is contained in:
parent
357cc568e9
commit
06d742a7f3
@ -16,7 +16,7 @@ interface RunOptions
|
|||||||
| Property | Modifiers | Type | Description |
|
| Property | Modifiers | Type | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| [preventDuplicates?](./bitburner.runoptions.preventduplicates.md) | | boolean | _(Optional)_ Should we fail to run if another instance is running with the exact same arguments? This used to be the default behavior, now defaults to false. |
|
| [preventDuplicates?](./bitburner.runoptions.preventduplicates.md) | | boolean | _(Optional)_ Should we fail to run if another instance is running with the exact same arguments? This used to be the default behavior, now defaults to false. |
|
||||||
| [ramOverride?](./bitburner.runoptions.ramoverride.md) | | number | <p>_(Optional)_ The RAM allocation to launch each thread of the script with.</p><p>Lowering this will <i>not</i> automatically let you get away with using less RAM: the dynamic RAM check enforces that all [NS](./bitburner.ns.md) functions actually called incur their cost. However, if you know that certain functions that are statically present (and thus included in the static RAM cost) will never be called in a particular circumstance, you can use this to avoid paying for them.</p><p>You can also use this to <i>increase</i> the RAM if the static RAM checker has missed functions that you need to call.</p><p>Must be greater-or-equal to the base RAM cost. Defaults to the statically calculated cost.</p> |
|
| [ramOverride?](./bitburner.runoptions.ramoverride.md) | | number | <p>_(Optional)_ The RAM allocation to launch each thread of the script with.</p><p>Lowering this will <i>not</i> automatically let you get away with using less RAM: the dynamic RAM check enforces that all [NS](./bitburner.ns.md) functions actually called incur their cost. However, if you know that certain functions that are statically present (and thus included in the static RAM cost) will never be called in a particular circumstance, you can use this to avoid paying for them.</p><p>You can also use this to <i>increase</i> the RAM if the static RAM checker has missed functions that you need to call.</p><p>Must be greater-or-equal to the base RAM cost. Will be rounded to the nearest hundredth-of-a-GB, which is the granularity of all RAM calculations. Defaults to the statically calculated cost.</p> |
|
||||||
| [temporary?](./bitburner.runoptions.temporary.md) | | boolean | _(Optional)_ Whether this script is excluded from saves, defaults to false |
|
| [temporary?](./bitburner.runoptions.temporary.md) | | boolean | _(Optional)_ Whether this script is excluded from saves, defaults to false |
|
||||||
| [threads?](./bitburner.runoptions.threads.md) | | number | _(Optional)_ Number of threads that the script will run with, defaults to 1 |
|
| [threads?](./bitburner.runoptions.threads.md) | | number | _(Optional)_ Number of threads that the script will run with, defaults to 1 |
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ Lowering this will <i>not</i> automatically let you get away with using less RAM
|
|||||||
|
|
||||||
You can also use this to <i>increase</i> the RAM if the static RAM checker has missed functions that you need to call.
|
You can also use this to <i>increase</i> the RAM if the static RAM checker has missed functions that you need to call.
|
||||||
|
|
||||||
Must be greater-or-equal to the base RAM cost. Defaults to the statically calculated cost.
|
Must be greater-or-equal to the base RAM cost. Will be rounded to the nearest hundredth-of-a-GB, which is the granularity of all RAM calculations. Defaults to the statically calculated cost.
|
||||||
|
|
||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import { toNative } from "../NetscriptFunctions/toNative";
|
|||||||
import { ScriptIdentifier } from "./ScriptIdentifier";
|
import { ScriptIdentifier } from "./ScriptIdentifier";
|
||||||
import { findRunningScripts, findRunningScriptByPid } from "../Script/ScriptHelpers";
|
import { findRunningScripts, findRunningScriptByPid } from "../Script/ScriptHelpers";
|
||||||
import { arrayToString } from "../utils/helpers/ArrayHelpers";
|
import { arrayToString } from "../utils/helpers/ArrayHelpers";
|
||||||
|
import { roundToTwo } from "../utils/helpers/roundToTwo";
|
||||||
import { HacknetServer } from "../Hacknet/HacknetServer";
|
import { HacknetServer } from "../Hacknet/HacknetServer";
|
||||||
import { BaseServer } from "../Server/BaseServer";
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
import { RamCostConstants } from "./RamCostGenerator";
|
import { RamCostConstants } from "./RamCostGenerator";
|
||||||
@ -180,6 +181,9 @@ function runOptions(ctx: NetscriptContext, threadOrOption: unknown): CompleteRun
|
|||||||
`RunOptions.ramOverride must be >= baseCost (${RamCostConstants.Base}), was ${result.ramOverride}`,
|
`RunOptions.ramOverride must be >= baseCost (${RamCostConstants.Base}), was ${result.ramOverride}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// It is important that all RAM calculations operate in hundredths-of-a-GB,
|
||||||
|
// otherwise we can get inconsistent rounding results.
|
||||||
|
result.ramOverride = roundToTwo(result.ramOverride);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -329,6 +333,7 @@ function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void {
|
|||||||
// rounding issues without exposing rounding exploits in ramUsage.
|
// rounding issues without exposing rounding exploits in ramUsage.
|
||||||
if (ws.dynamicRamUsage > 1.00000000000001 * ws.scriptRef.ramUsage) {
|
if (ws.dynamicRamUsage > 1.00000000000001 * ws.scriptRef.ramUsage) {
|
||||||
log(ctx, () => "Insufficient static ram available.");
|
log(ctx, () => "Insufficient static ram available.");
|
||||||
|
const functionsUsed = Object.keys(ws.dynamicLoadedFns).join(", ");
|
||||||
const err = errorMessage(
|
const err = errorMessage(
|
||||||
ctx,
|
ctx,
|
||||||
`Dynamic RAM usage calculated to be greater than RAM allocation.
|
`Dynamic RAM usage calculated to be greater than RAM allocation.
|
||||||
@ -337,6 +342,7 @@ function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void {
|
|||||||
Threads: ${ws.scriptRef.threads}
|
Threads: ${ws.scriptRef.threads}
|
||||||
Dynamic RAM Usage: ${formatRam(ws.dynamicRamUsage)} per thread
|
Dynamic RAM Usage: ${formatRam(ws.dynamicRamUsage)} per thread
|
||||||
RAM Allocation: ${formatRam(ws.scriptRef.ramUsage)} per thread
|
RAM Allocation: ${formatRam(ws.scriptRef.ramUsage)} per thread
|
||||||
|
Functions in-use: [${functionsUsed}]
|
||||||
|
|
||||||
One of these could be the reason:
|
One of these could be the reason:
|
||||||
* Using eval() to get a reference to a ns function
|
* Using eval() to get a reference to a ns function
|
||||||
|
3
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
3
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -270,7 +270,8 @@ interface RunOptions {
|
|||||||
* You can also use this to <i>increase</i> the RAM if the static RAM checker has missed functions
|
* You can also use this to <i>increase</i> the RAM if the static RAM checker has missed functions
|
||||||
* that you need to call.
|
* that you need to call.
|
||||||
*
|
*
|
||||||
* Must be greater-or-equal to the base RAM cost. Defaults to the statically calculated cost.
|
* Must be greater-or-equal to the base RAM cost. Will be rounded to the nearest hundredth-of-a-GB,
|
||||||
|
* which is the granularity of all RAM calculations. Defaults to the statically calculated cost.
|
||||||
*/
|
*/
|
||||||
ramOverride?: number;
|
ramOverride?: number;
|
||||||
/**
|
/**
|
||||||
|
@ -9,6 +9,7 @@ import { ScriptArg } from "@nsdefs";
|
|||||||
import { isPositiveInteger } from "../../types";
|
import { isPositiveInteger } from "../../types";
|
||||||
import { ScriptFilePath } from "../../Paths/ScriptFilePath";
|
import { ScriptFilePath } from "../../Paths/ScriptFilePath";
|
||||||
import { sendDeprecationNotice } from "./common/deprecation";
|
import { sendDeprecationNotice } from "./common/deprecation";
|
||||||
|
import { roundToTwo } from "../../utils/helpers/roundToTwo";
|
||||||
import { RamCostConstants } from "../../Netscript/RamCostGenerator";
|
import { RamCostConstants } from "../../Netscript/RamCostGenerator";
|
||||||
|
|
||||||
export function runScript(path: ScriptFilePath, commandArgs: (string | number | boolean)[], server: BaseServer): void {
|
export function runScript(path: ScriptFilePath, commandArgs: (string | number | boolean)[], server: BaseServer): void {
|
||||||
@ -23,7 +24,7 @@ export function runScript(path: ScriptFilePath, commandArgs: (string | number |
|
|||||||
});
|
});
|
||||||
const tailFlag = flags["--tail"] === true;
|
const tailFlag = flags["--tail"] === true;
|
||||||
const numThreads = parseFloat(flags["-t"] ?? 1);
|
const numThreads = parseFloat(flags["-t"] ?? 1);
|
||||||
const ramOverride = flags["--ram-override"] != null ? parseFloat(flags["--ram-override"]) : null;
|
const ramOverride = flags["--ram-override"] != null ? roundToTwo(parseFloat(flags["--ram-override"])) : null;
|
||||||
if (!isPositiveInteger(numThreads)) {
|
if (!isPositiveInteger(numThreads)) {
|
||||||
return Terminal.error("Invalid number of threads specified. Number of threads must be an integer greater than 0");
|
return Terminal.error("Invalid number of threads specified. Number of threads must be an integer greater than 0");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user