109 lines
3.2 KiB
GDScript
109 lines
3.2 KiB
GDScript
extends SceneTree
|
|
|
|
const BenchmarkScript := preload("res://simulation/benchmark/LoadedResourceDiscoveryBenchmark.gd")
|
|
const RESOURCE_COUNTS := [18, 180, 1800]
|
|
const BENCHMARK_SEED := 17331
|
|
const DEFAULT_OUTPUT_PATH := "res://logs/loaded_resource_discovery.json"
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
|
|
func _run() -> void:
|
|
var benchmark := BenchmarkScript.new()
|
|
var cases: Array[Dictionary] = []
|
|
var include_spatial := not _has_argument("--linear-only")
|
|
for resource_count in RESOURCE_COUNTS:
|
|
var fixture := benchmark.create_fixture(root, resource_count, BENCHMARK_SEED)
|
|
var result := benchmark.measure_fixture(
|
|
fixture,
|
|
_get_integer_argument(
|
|
"--queries=", LoadedResourceDiscoveryBenchmark.DEFAULT_QUERY_COUNT
|
|
),
|
|
_get_integer_argument(
|
|
"--samples=", LoadedResourceDiscoveryBenchmark.DEFAULT_SAMPLE_COUNT
|
|
),
|
|
include_spatial
|
|
)
|
|
benchmark.free_fixture(fixture)
|
|
if result.is_empty():
|
|
push_error(
|
|
"Loaded-resource discovery benchmark failed at %d resources" % resource_count
|
|
)
|
|
quit(1)
|
|
return
|
|
cases.append(result)
|
|
_print_case(result)
|
|
|
|
var report := {
|
|
"schema_version": LoadedResourceDiscoveryBenchmark.SCHEMA_VERSION,
|
|
"workload_id": String(LoadedResourceDiscoveryBenchmark.WORKLOAD_ID),
|
|
"benchmark_seed": BENCHMARK_SEED,
|
|
"host_label": _get_argument_value("--host-label=", "unlabelled"),
|
|
"godot_version": Engine.get_version_info().get("string", "unknown"),
|
|
"resource_counts": RESOURCE_COUNTS,
|
|
"resource_spacing": LoadedResourceDiscoveryBenchmark.RESOURCE_SPACING,
|
|
"inclusions":
|
|
[
|
|
"loaded_resource_candidate_discovery",
|
|
"authoritative_availability_and_scoring",
|
|
"reservation_and_release",
|
|
],
|
|
"exclusions":
|
|
[
|
|
"fixture_construction",
|
|
"simulation_tick",
|
|
"serialization",
|
|
"rendering",
|
|
"navigation_pathfinding",
|
|
],
|
|
"cases": cases,
|
|
}
|
|
var output_path := _get_argument_value("--output=", DEFAULT_OUTPUT_PATH)
|
|
var output := FileAccess.open(output_path, FileAccess.WRITE)
|
|
if output == null:
|
|
push_error("Could not write loaded-resource report to %s" % output_path)
|
|
quit(1)
|
|
return
|
|
output.store_string(JSON.stringify(report, "\t") + "\n")
|
|
output.close()
|
|
print("[BENCH] Report: %s" % ProjectSettings.globalize_path(output_path))
|
|
quit(0)
|
|
|
|
|
|
func _print_case(result: Dictionary) -> void:
|
|
var linear: Dictionary = result["linear"]
|
|
var message := (
|
|
"[BENCH] %4d resources | linear %7.2f us/query"
|
|
% [result["resource_count"], linear["usec_per_query_median"]]
|
|
)
|
|
if result.has("spatial"):
|
|
var spatial: Dictionary = result["spatial"]
|
|
message += (
|
|
" | spatial %7.2f us/query | %.2fx | %.1f inspected"
|
|
% [
|
|
spatial["usec_per_query_median"],
|
|
result["speedup"],
|
|
spatial["candidates_inspected_average"],
|
|
]
|
|
)
|
|
print(message)
|
|
|
|
|
|
func _has_argument(argument: String) -> bool:
|
|
return argument in OS.get_cmdline_user_args()
|
|
|
|
|
|
func _get_integer_argument(prefix: String, default_value: int) -> int:
|
|
return maxi(int(_get_argument_value(prefix, str(default_value))), 1)
|
|
|
|
|
|
func _get_argument_value(prefix: String, default_value: String) -> String:
|
|
for argument in OS.get_cmdline_user_args():
|
|
if argument.begins_with(prefix):
|
|
var value := argument.trim_prefix(prefix)
|
|
if not value.is_empty():
|
|
return value
|
|
return default_value
|