mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 12:15:44 +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 |
|
||||
| --- | --- | --- | --- |
|
||||
| [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 |
|
||||
| [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.
|
||||
|
||||
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:**
|
||||
|
||||
|
@ -28,6 +28,7 @@ import { toNative } from "../NetscriptFunctions/toNative";
|
||||
import { ScriptIdentifier } from "./ScriptIdentifier";
|
||||
import { findRunningScripts, findRunningScriptByPid } from "../Script/ScriptHelpers";
|
||||
import { arrayToString } from "../utils/helpers/ArrayHelpers";
|
||||
import { roundToTwo } from "../utils/helpers/roundToTwo";
|
||||
import { HacknetServer } from "../Hacknet/HacknetServer";
|
||||
import { BaseServer } from "../Server/BaseServer";
|
||||
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}`,
|
||||
);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
@ -329,6 +333,7 @@ function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void {
|
||||
// rounding issues without exposing rounding exploits in ramUsage.
|
||||
if (ws.dynamicRamUsage > 1.00000000000001 * ws.scriptRef.ramUsage) {
|
||||
log(ctx, () => "Insufficient static ram available.");
|
||||
const functionsUsed = Object.keys(ws.dynamicLoadedFns).join(", ");
|
||||
const err = errorMessage(
|
||||
ctx,
|
||||
`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}
|
||||
Dynamic RAM Usage: ${formatRam(ws.dynamicRamUsage)} per thread
|
||||
RAM Allocation: ${formatRam(ws.scriptRef.ramUsage)} per thread
|
||||
Functions in-use: [${functionsUsed}]
|
||||
|
||||
One of these could be the reason:
|
||||
* 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
|
||||
* 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;
|
||||
/**
|
||||
|
@ -9,6 +9,7 @@ import { ScriptArg } from "@nsdefs";
|
||||
import { isPositiveInteger } from "../../types";
|
||||
import { ScriptFilePath } from "../../Paths/ScriptFilePath";
|
||||
import { sendDeprecationNotice } from "./common/deprecation";
|
||||
import { roundToTwo } from "../../utils/helpers/roundToTwo";
|
||||
import { RamCostConstants } from "../../Netscript/RamCostGenerator";
|
||||
|
||||
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 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)) {
|
||||
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