Skip to main content

performance-profiling

Diagnose or improve LunCoSim FPS, physics time, periodic stalls, Builder versus View differences, terrain/render cost, or Tracy captures. Use when performance must improve architecturally without changing BigSpace, substeps, shadows, terrain quality, or image fidelity.

Datos de origen

Repositorio
LunCoSim/lunco-sim
Última actividad en el origen
28 de octubre de 2026 a las 07:59
Idioma detectado de SKILL.md
inglés
Estrellas
106
Forks
21

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
performance-profiling
description
Diagnose or improve LunCoSim FPS, physics time, periodic stalls, Builder versus View differences, terrain/render cost, or Tracy captures. Use when performance must improve architecturally without changing BigSpace, substeps, shadows, terrain quality, or image fidelity.
# Performance profiling: measure the owner, then remove avoidable work Read the current handover in [`docs/reviews/open-400fps-performance-handover.md`](../../docs/reviews/open-400fps-performance-handover.md) before changing code. A status-bar FPS number is a symptom, not an attribution. ## Required separation - Run one production session that you own for the product FPS number, launched from the task checkout on a verified free API port. Do this even if another user's or agent's session is active; never control, stop, restart, or change the scene in a pre-existing session. Report concurrent GPU/CPU workloads and classify affected numbers as contention-affected, not clean acceptance. Do not use Tracy's instrumented number as acceptance evidence. Record the admitted Twin source revision and require its expected authored verdict before comparing completed-mission windows. A tick threshold or zero process exit does not prove acceptance. Exclude source/API errors, and require readiness and diagnostics to pass for the measured cohort. Native presentation failure appears in `RuntimeDiagnostics` under producer `render-recovery`; `presentation-stopped` is an error even when physics and the API remain usable. Application-frame FPS can keep advancing without rendered scene output. Reject such a cohort; do not interpret its frame rate as graphics performance or cure it by lowering quality implicitly. Compare the recorded Twin commits explicitly; two individually clean checkouts can have different revisions. Such runs are different source cohorts, even if their scenario name and application binary match. Initialization-source and milestone equality alone do not prove exact native-state replay. - Run a separate Tracy build/capture using the adjacent `../tracy` checkout; start the matching `tracy-capture` before the production binary and inspect the settled window, not only startup. Bevy 0.20 uses Tracy 0.14.1; the matching official tools are `../tracy/capture/build/tracy-capture-0.14.1` and `../tracy/csvexport/build/tracy-csvexport-0.14.1`. Older capture tools cannot read the new client protocol. On Linux, the adjacent Tracy client supports `TRACY_SAMPLING_HZ`; record the requested rate and verify the saved capture's sampling period. Its default 10 kHz CPU sampling can add substantial overhead. A lower sampling rate is useful for a separate zone-attribution run; it is still not FPS acceptance. Select native physics zones for broad phase, narrow phase, solver preparation, substeps, integration and CCD. Keep `lunco_physics::order_audit` disabled unless deterministic ordering itself is the measurement subject. Check the profiler listener and connection against the owned PID with `ss -ltnp`/`ss -tnp`. A concurrent Tracy client can occupy 8086 and move the owned app to the next port; pass that port with `tracy-capture -p`. A capture from another process is not evidence for the task scene. A zero collector exit does not prove capture integrity. Compare the saved file size with the collector's reported compressed payload plus native file framing, and require a successful native CSV export before using its zones. `FileWrite::GetCompressionStatistics` excludes the six-byte file header and four-byte length per compressed block; these bytes are present on disk. A size mismatch, parser failure or stalled export leaves that capture unusable. A reported instrumentation failure also makes the requested window incomplete. Keep hot zone names bounded: step ids, timestamps, and measured durations must not be span fields when the Tracy layer uses those values as source-location identity. Inspect the exact owned exporter process before terminating an unsuccessful read; do not restart a still-running export solely because an observation timed out. Check disk space while the owned app is live as well as after it exits. Native capture writing can overlap runtime allocations, and the collector can report success despite a truncated file. Native unwrapped CSV rows are grouped by source location; sort by `ns_since_start` before reconstructing chronological phases or transitions. Create the ignored capture directory and check that the collector is still alive before launching the app. A failed collector must not leave an unconnected instrumented client accumulating events. If fine executor bookkeeping dominates the diagnostic, a separately labelled cohort may use `RUST_LOG=info,bevy_ecs::schedule::executor=warn`; retain system, schedule and native physics spans and never compare that cohort as an isolated speedup against a different filter. Exact-zone CPU selection matches the zone's own thread: a FixedMain main-thread selection excludes concurrent Bevy workers. For sampled CPU stacks within a slow zone, use the read-only [`scripts/perf/tracy_samples.cpp`](../../scripts/perf/tracy_samples.cpp) tool and its [build/interpretation instructions](../../scripts/perf/README.md#saved-cpu-samples). Match the capture's Tracy release when building its server library, verify the owned PID, and select the zone's exact thread and time interval. Samples can be narrowed to complete instances of one exact zone by appending its name to the sample export command; inspect `matched_zones` and the terminal result. Frame-wide samples include unrelated work outside the selected child zone. The native exporter supports `-e -u` for per-event self times. Match those rows to the inclusive export by source, thread and start before selecting a bounded window: self duration does not provide the event's original end. For one complete schedule subtree, require the selected self-time sum to equal its inclusive duration. Main-thread schedule self time includes waits for worker systems; it does not by itself prove executor overhead. Profiling data stays in ignored `scripts/perf/captures/`, `.cache/` or `target/perf/`; commit reusable tool sources and documentation only. - Compare Builder and View with the same scene, camera, rendering-quality settings, physics substeps, shadow settings, and terrain assets. A Builder- only cost usually means an editor observer, rebuild, projection, or UI path, not that physics needs a different global timestep. - For a settled DEM quality window, require `TerrainLodStatus.stream.wanted == resident`, `stream.pending == 0`, `derived.active == false`, `derived.pending == 0`, and `derived.ready == derived.total`. Record those owner facts before and throughout the window alongside camera and quality inputs. Simulation readiness alone does not certify optional visual-map preparation. Keep this measurement gate out of simulation admission. Audit a surface camera with `world_pos` and `world_rotation` in the active simulation frame; `visual_foci` reports composed root coordinates, which move with celestial ancestors even when the camera is stationary over the terrain. - Assert the intended fixture before timing an owner-resolution benchmark. `PortRegistry::default()` installs the generic input owner first; registering other backends afterward does not make them precede it. A synthetic precedence fixture must verify its resolved owner index. The ignored `lunco-port-core` `multi_port_transaction_diagnostic` measures 2,048 complete atomic transactions over 32 entities with 1, 8 or 32 inputs each, behind five registered but absent component owners. It asserts the winning backend and exact final scalar bits. Report every width, including regressions, and qualify the actual scene separately: a multi-input fixture gain does not establish a faster production exchange. - Attribute CPU, GPU, physics, terrain, and UI separately. Never disable shadows, lower authored terrain quality, change BigSpace, or change the standard substep count to make a graph look better. For typed hook conversion, `lunco-hooks-rhai`'s ignored `map_conversion_diagnostic` measures complete nested-map conversion at 8, 128 and 2,048 entries in sorted, reverse and permuted order. Compare every case with independent executable snapshots and alternating runs, without a concurrent build. This fixture uses the test allocator; pair it with the production UI-preparation gate and an owned scene before claiming runtime effects. A fixture improvement is not a whole-frame or loading improvement. Snapshot compiler-managed executables with independent copies, for example `cp --reflink=auto`, never hard links. Rebuilding can overwrite every hard link to a test artifact. Verify separate device/inode identities and record hashes before and after the comparison; reject results if a snapshot changed or a supposed code variant resolved to the same executable. Before grouping static shapes, inspect native child-pose invalidation and material inheritance. Preserve mutable global material defaults; a lower body count alone does not prove a speedup or equivalent physical behavior. For pose-bridge selection, the ignored `pose_invalidation_diagnostic` in `lunco-usd-avian-core` measures 512 bodies over 256 persistent-system runs. Preserve its separate leaf, render-branch, above-frame and physical-parent cases; require exact native poses, velocities and leaf representation history. Pair it with a normal production window before claiming scene-level savings. `collider_composition_diagnostic` in the same owner runs 512 colliders over 256 iterations for ancestor translation, rotation, scale, physical-parent motion and an irrelevant leaf. Require exact transform fingerprints across independent variants and retain the cached-prefix hierarchy-depth check. In a diagnostics-enabled render host, `lunco-render-bevy` adds `lunco_shadow_shared_early`/`late` and `lunco_shadow_camera_early`/`late` timestamps around the native shadow passes. Shared events correspond to individual point/spot views; camera events include that camera's directional cascades. Check all four names and their event counts before attributing total shadow cost. Late spans can contain only timestamp overhead. Use the existing Tracy build for native GPU export: Bevy 0.20's `trace_tracy` enables the render diagnostics recorder through `bevy_render/tracing-tracy`. Inspect timestamp support and recorded pass coverage before claiming a complete GPU total; a sum of recorded passes excludes uninstrumented work and inter-pass gaps. Use the early shared child spans `lunco_light_depth/<pass_name>` when attributing individual maps; native exports prefix them with `lunco_shadow_shared_early/`. Do not sum child and parent times. `lunco_shadow_view_work` supplies admitted viewport dimensions, optional phase emptiness and native bin/set counts. This brief CPU snapshot is not pass execution time; bins are not draw counts and stable counts do not prove static caster inputs. Native labels identify current render allocations, not authored lights. Close each child before its parent. Retain native dependency ordering, native-parameter admission before begin and render-context buffer order when changing this adapter. Reapply PBR's system-local early/late ordering rules after removing the original system; retaining its implicit type set alone preserves only dependencies targeting that set. Check the actual shadow image before admitting a capture as performance evidence. Qualify point/spot roots with the `shared_shadow_allocation` graphics fixture before comparing native builders. Its positive and negative pixel probes cover the separate shared-light schedule; camera shadows alone do not. `SharedShadowView` uses the native single-threaded executor for its serial GPU chain or two CPU-mode shadow passes. Native render preparation clears indirect parameter buffers once per frame before view work. Attribute its inclusive and self costs separately; frame-level Render and camera Core3d still use their existing executors. Verify native pass inventory and final buffer order before comparing executor costs. This render adapter does not change solver cadence or authoritative simulation ordering. Unsupported timestamp features or exhausted per-frame queries leave incomplete GPU evidence, not zero cost. - For intermittent long frames, export individual CPU zones and correlate them with perspective/window markers. Exclude screenshot delivery, authored test verdicts and perspective transitions from settled statistics. Inclusive render/extraction schedules can contain a native `queue_submit` wait; report the submission boundary separately from owner computation. A long submission span alone does not establish its driver, GPU or scheduling cause. Retain periodic GPU clocks/utilization, CPU pressure and concurrent process evidence, then run the same exact uninstrumented artifact separately. Failure to reproduce an earlier tail in a later run does not prove a fix. Record visible popup/UI state alongside camera and graphics settings. For JSON-scope stalls, distinguish authored source catalogs from completed experiment histories. The asset/Twin owner publishes `JsonAssetContent::PersistedResult` as identity-only metadata, projecting the `persisted_result` Rhai fact without loading or copying result bodies. These entries own no Bevy text handle and never delay JSON-scope readiness; loading counts cover authored reads only. The existing application asset policy skips those records before JSON decoding. Confirm the `application_json_catalogs` production gate and measure the same admitted source cohort. Do not hide malformed authored catalogs, change Rhai limits or classify sources by guessed catalog filenames. For coupled startup, distinguish the one-shot solve from participant certification. Pending constructors supply no certifiable observation; the owner waits on their outcomes and revalidates current source, wiring and physical samples at final admission. Include coordinator counts and main-thread time when measuring startup; worker timing alone misses repeated certification work. Bootstrap API readiness does not certify the requested Twin. Record the exact active Twin and its physics admission. An interactive replacement retires the startup failure guard on `TwinClosed`; a late canceled asset result must not terminate the replacement. The focused production gate is `scripts/api/test_startup_scene_replacement.py --port <free-port> --log-dir <ignored-evidence-directory>`. Record prepared-solver hits and native attempts/hits/compilations alongside startup time; tests and other Twins can legitimately evict bounded artifacts. An immediate repeat with unchanged inputs distinguishes cold-cache work from recurring constructor cost without changing retention limits. For Modelica native-construction costs, distinguish selected application work from whole-source preparation. Projection reuse storage is needed only for selected source programs and is shared across that application's issued colors. Preserve checked identity, input validation and evaluation order. Compare the same prepared component's complete f64 states alongside construction timing; include its first complete observation. Zero native compilations do not prove faster admission: reference evaluation can dominate a large coupled initializer even when it avoids JIT work. Keep an evaluator change only when the actual scene improves with its numerical contract intact. Before changing an artifact-cache codec, sample its complete lookup zone. Checked deserialization may spend most of its time reconstructing native structural contracts; parsing and decompression must be attributed separately. Do not bypass those checks to improve a disk-hit number. Shared-value construction also pays for source discovery and symbolic proofs. Its read collector shares the exhaustive Solve operand checks in one traversal; preserve range/context checks and whole-program equivalence when optimizing it. The symbolic term table interns complete operation keys once; each scalar output uses the table-local ID and output ordinal. Retain full structural equality and the shared table lifetime across segments and both sides of a check. Scalar terms carry the original slot or operation/output identity directly; there is no separate scalar-term interning table. Preserve disjoint identity domains and the independent checker's complete walks when changing storage. Operation shapes use the complete typed IR encoding, including floating-point bits. A changed constant's bits must fail the checker; hash equality alone cannot establish operation identity. Private proof lookup tables use Rumoca's existing fast hasher. Preserve full key equality and program-order ID assignment. Qualify constructor costs with recorded prepared/native-cache hits and the fixed MSL canary; isolated proof benchmarks do not establish faster scene admission. Exclude overlapping builds/apps and record local dependency patches separately from the portable lockfile. Dependency changes require the repository's explicit authorization before edits. For fixed RK4, verify that its ME component receives the opaque execution backend issued by `rumoca_sim::fmi_execution_backend`. Selecting a fixed integrator does not itself install compiled evaluation. Keep the same lattice, input transaction and complete checked observation when comparing native and reference execution. The nonlinear-array differential test qualifies numerical agreement; its small diagnostic timing does not certify whole coupled ticks. Use actual compiler-cache accounting on nontrivial production models to verify native work. A local dependency path patch can disable prepared-model disk caching; record that state and reject it as final loading acceptance for a portable Git pin. For terrain certificate lookups, whole-cell identity is the fenced surface and the two raster indices. Refined rectangles also retain exact coordinate bits. Keep one FIFO capacity and the same cache-independent interval and refinement admission. Use the certified occlusion mechanism checks and production solar visibility, night and invalid-admission gates. Compare the actual solar zones in matched settled captures; a smaller synthetic lookup time is not whole-tick or graphics acceptance. Measure first scene readiness against the requested active Twin and spawned physical root. Bootstrap readiness precedes Twin admission; do not use a minimum elapsed-time filter to distinguish them. Record landing as a separate mission milestone. Preserve source hashes and native construction/cache accounting. For USD startup snapshots, attribute native path/field resolution separately from file loading and ECS publication. Share the library's `BindingCache` only within one immutable stage snapshot; preserve purpose resolution, native collection membership and invalid material-target errors. Qualify an SDK update against the same Twin revision and a regular production readiness/landing run before claiming a loading gain. Dependency source edits still require explicit permission. ## Architecture checks Frame-conversion and collider-admission kernels are owned by `lunco-usd-avian-core`; its regular development build uses optimization level three with development checks retained. Follow the actual owning package when profiling moved kernels. Collider propagation must independently drain parent, transform and body removals before comparing performance; a stale relative transform invalidates a faster result. Shader-port writes are fixed-step consumers even though their downstream GPU binding runs at presentation cadence. Measure the actual backend with the ignored `shader_input_transaction_benchmark` owner diagnostic, including both unchanged and changing values. Its declaration and material-intent packages use regular development optimization level three. Preserve live validation and no-op change detection; a large visual binding count alone does not authorize changing clocks or skipping writes. The shader metadata callback uses the already-selected live slot. Preserve authored-type precedence over a differently typed live override, rejection of untyped drives, and current drive membership before accepting a faster result. When comparing native CPU/GPU instance preparation, retain the same PBR, shadows, meshes and quality. The desktop composition selects native CPU preparation; qualify changes with both `shared_shadow_allocation` and `vertex_shadow_alignment` pixel gates and source-matched normal Twin windows. Keep the per-scene tradeoffs visible: the GPU path can have a lower median in some scenes. Device capability is not active-path evidence: camera `NoCpuCulling` requires native `RenderMeshInstances::GpuBuilding` and indirect drawing. `NoIndirectDrawing` views need CPU frustum tests. Preserve foreign-owned markers when reconciling these structural changes. Native camera and shadow batch modes must also match the active builder. CPU preparation admits effective `GpuPreprocessingMode::None` after native device support initialization on every `RenderStartup`, including recovery. A faster cohort with missing geometry is a failed visual comparison, regardless of FPS or readiness diagnostics. For GPU-only buffer layout, preserve deterministic scalar math and validate shader array stride at the native allocator. `UninitBufferVec` uses encase's `<[T; 1]>::SHADER_SIZE`: a shader element's minimum size alone does not include all array alignment. Owner regressions cover both structure padding and `vec3` array stride. Verify the actual terrain image and retained render diagnostics when admitting native GPU preparation. For co-simulation input writes, preserve the port owner's live metadata and precedence checks. Initial handoff and live exchange use `input_transaction`: immutable staging and commit share one exclusive world borrow, so each eligible target is validated once. Returning an error rejects the staged batch. A retained command preparation has no such borrow guarantee and must still be revalidated at commit. Do not replace either proof with a revision-only cache. The scoped transaction's Bevy hash table stores indexes into its staged writes; duplicate checks compare full identities without cloning the port names again. Its compact records retain only the admitted callback, entity, name, slot and value. Preserve full metadata snapshots for independently retained preparations; only the uninterrupted transaction borrow permits releasing admission metadata. Unit-reference clones share immutable definitions, coordinate-frame clones share immutable text, and Avian reuses its fixed built-in unit references. Preserve exact text/hash/serialization behavior and reject blank frame identities. This storage sharing never caches the live port owner, bounds, frame or permission. The bounded debug spans `port_input_transaction_stage` and `port_input_transaction_commit` separate validation from application when `lunco_port_core::ports=debug` is enabled. When reducing shader commit lookups, retain Bevy change detection: borrow the component once, inspect through its shared dereference and mutate only a changed slot. The owner diagnostic measures both constant and changing transactions; `lander_plume_activity` verifies connected shader delivery and rejected scalar range writes through the production scene-test host. Before a wheel-shape comparison, verify the coordinate contract in `docs/architecture/21-domain-usd.md`. Compare the native collider's axial and radial bounds with its authored geometry and mechanical axle. Preserve the admitted geometry through a restart: disposable view edits are discarded when the clean source document refreshes. For an isolated unsaved comparison, use the normal document journal, do not save it, and verify source hashes after exit. For synchronous USD edit stalls, inspect compound operation count and native composition lifetime. The document owner's `UsdEditSession` shares one current authoring stage across an ordered sequence; direct layer changes invalidate it. Preserve the private candidate and atomic rejection boundary described in [architecture 21](../../docs/architecture/21-domain-usd.md). Measure the actual command in a production run; a faster edit still occupies its calling thread. Also inspect `usd_native_reference_discovery`: native property resyncs prepare only their asset values, while prim resyncs scan the affected subtree. Asset types gate provenance and time-sample resolution. Domain live-edit owners consume one complete notice batch in place; label changes must preserve live child state. Modelica coupling holds `FixedMain`, while the pacing clock retains running demand in `Time<Fixed>::overstep`. Compare completed simulation time against monotonic wall time and inspect pending demand through `SimulationTimingProfile`; a short native physics service time does not certify realtime co-simulation. When a coupled sensor changes with host pacing, compare its full input values before attributing the difference to solver math. Contact impulses belong to the completed master interval; `lunco-physics::contact_of` owns load normalization for ports and telemetry. Native admission delta may be zero while that sample remains valid. Exercise `scripts/api/test_contact_force_hold.py` through the production scene-test host when changing this boundary; its authored observer checks loaded contact, held time, retained force and an unavailable surface. Physical render easing consumes the time owner's bounded `SimulationPresentationTime.interpolation` snapshot; full queued cycles are never a render extrapolation factor. Compare successive sample ticks across coupling waits and pause/resume: they must not decrease within one mission. Celestial and interaction clocks retain their separate owners. The common application plugin uses native endpoint capture/restore with public custom-easing markers. Do not remove queued time or loosen quaternion admission to conceal an invalid render pose. For scene-test diagnostics, `--tick-hz` varies manual update pacing; use the runtime's `Time<Fixed>` quantum and elapsed time when interpreting physics cost. Completed Modelica receipts have one reader in `SimulationCompletions`, serviced before clock projection, before admission of a held pending fixed cycle, and by the native driver on response readiness between application updates. A ready receipt can release another cycle in the same update; unfinished work yields without a wait. Full presentation isolation remains a separate requirement. Native headless readiness is shared through `SimulationCompletionSources` for participant workers. Its worker leases control registration lifetime; readiness does not consume a receipt. Windowed hosts never block on this wait. Complete-cycle continuation checks both coupling and generic progress holds. For runtime UI policy work, compare actual immutable input snapshots as well as producer change ticks. Equal facts must not schedule another projection merely because a presentation component received an equal-value write. Preserve hook generation, source lifetime, caller identity and derived vessel invalidation. Attribute `exposure_runtime_surface_facts` separately from its publisher and worker policy spans. Public output selection uses the port owner's name index and live slot order; preserve complete output facts and unsampled-port semantics. The ignored `runtime_output_facts_diagnostic` in `lunco-luncosim-exposures` measures complete output projection, including all-value allocation. Compare independent binaries and qualify the authored public-output consumer in a production session; fixture timing alone does not establish a scene speedup. The default communication period is one physics tick; longer periods must be authored explicitly. Physical celestial sampling uses `CelestialClock::epoch_at_tick`, with `celestial_physical_inputs` at interval start before environment computation and `celestial_physical_endpoint` after native writeback. The component's tick is the admitted cycle, and the sampler owns its phase. Presentation's angular error gate never chooses physical inputs. Directions, gravity and solar visibility share `SimulationPoseQuery`; do not restore raw hierarchy readers for moving probes. Reuse the ephemeris provider's exact-epoch cache. Attribute sampling separately from native physics and from the rendered celestial chain; its cost must not be hidden inside a physics-only timing number. For deliberately frozen captures use `StepSimulation` and presentation-timed sequencing. Manual demand uses the same fixed runner as paced execution and still respects preparation and solver barriers. A native hold gates the entire simulation; compare `clock_snapshot().physics_elapsed_s` and `fixed_elapsed_s` at completed-cycle boundaries before interpreting throughput measurements. Attribute numerical service separately from transaction dispatch and result admission. Live workers pass the exact communication point to the existing `LiveStepper::advance_to` boundary; adaptive Rumoca sessions and fixed prediction own their internal steps. Preserve the fixed prediction lattice, event handling, input sampling and finite/completion validation when optimizing that path. Do not add another worker-side integration grid or catch-up planner. For replay divergence, enable `RUST_LOG=info,lunco_modelica_worker::step_audit=debug` in a separate diagnostic run. Compare session-relative step ids, communication times and ordered input/ output fingerprints for each exact participant identity. These bounded log records locate differences; hash equality cannot prove state equality. Use `trace` for complete accepted samples, or `ReadModelicaStepSamples` for selected values in the last accepted transaction. Full traces can produce large logs and perturb scheduling; check storage and retain an uninstrumented acceptance run. Never infer a numerical repair solely because tracing hides a divergence. Keep communication-clock checks at floating point roundoff scale, with finite timestamps required at both request and completion admission. A solver's state tolerance must not loosen its communication endpoint validation. Validate the endpoint using `start + dt`; subtracting large absolute timestamps can reject a valid short interval through cancellation. UI exposure publication is paced by `Time<Real>`, independent of simulation pause and rate. Its dirty-state gate still coalesces unchanged facts. Attribute main-thread snapshot capture separately from `runtime_ui_policy_preparation` and owner publication. Native pure policy evaluation uses shared bounded worker admission, retaining captured hooks and caller context; one job plus one latest pending snapshot per surface bounds work. Source and identity changes fence completion. The wasm kernel is currently cooperative, not an isolated worker. Wait for ready surfaces and inspect preparation failures before taking a UI performance cohort. This boundary does not isolate the entire fixed runner from the presentation thread. Keep mission/timeline waits and telemetry deadlines on their declared simulation clocks; changing their timers to wall time changes simulation semantics. For script cost, attribute `rhai_native_task_tick` by stable actor gid and compare the same task-invocation range or simulation phase. Equal wall-time windows need not contain the same mission work when realtime pacing differs. Task callbacks borrow the persistent map through Rhai's bound receiver; see [the callback contract](../../docs/architecture/rhai-task-tree.md#leaf-callback-contract). Preserve captures, imports, state/error semantics and fixed cadence while removing copies at that boundary. For cost or memory that grows with runtime, check interpreter scope lifetime: initialized globals persist, while per-call constants and function locals must be released on both success and error. Use Rhai's scope-rewinding option at every scenario call boundary; do not periodically clear live scenario state. For Rhai presentation cost, inspect helper arguments and array iteration for copies of nested facts. Project the fields a helper consumes before calling it; indexed access can count participant statuses without copying their model input/output maps. Preserve the public hook facts and compare complete property outputs, including empty and unavailable states. Use paired real-owner spans for attribution; synthetic large-payload timings alone do not establish FPS. For typed Rhai boundary cost, use the shared `lunco-hooks-rhai` converter. It borrows input containers; embedding owners lower native leaves through `dynamic_to_hook_with_native`. Do not build a normalized Dynamic tree before calling it, clone containers to inspect their type, or add another recursive converter. Preserve native f64 math, unsigned integers, shared values and visible rejection of unsupported types. Check the interpreter resource seam with `typed_conversion_rejects_nested_native_values_without_cloning_them`, then exercise production typed command/query consumers, including a negative case. For port-exchange cost, inspect `BindingStatus.connections` and join targets to `ListPorts` owner metadata. The causal-state sink count is not the number of compiled wire targets: scene/shader inputs also participate in the exchange. Separate `cosim_exchange_write` from accumulation before changing routing. Preserve live metadata, bounds, ownership and stale-slot checks. For shader-name cost, use the shared borrowed converter described in [shader parameters](../../docs/architecture/shader-layers-and-params.md); canonical-name lookup must not allocate, and entities without `ShaderLook` must reject before conversion. Allocation probes and kernel timings do not certify whole-scene FPS. For native physics ordering investigations, enable `lunco_physics::order_audit=debug` in an owned diagnostic session. The continuous owner records native body and collider identities, poses, mass/inertia and velocities, plus contact-graph IDs, colours, manifold indices and prepared point geometry at the physics clock. Compare the first divergence before attributing a difference to pool size. This logging is diagnostic and must be disabled for performance acceptance. Partial pose checkpoints do not prove full-state replay. Compound audit rows include native scale and local part mass properties. If the first divergence is already in COM, compare admitted geometry and mass ownership before attributing later motion to the query dispatcher. For time-zero mass/inertia, inspect `PhysicsGeometryAdmission` before changing the authored checkpoint or reference. The shared native geometry schedule must finish before USD publishes physics-ready; advancing a solver tick to prepare geometry would change the initial state. Qualify preparation changes with the rootless scale/mass mechanism check and the unchanged four-rover production gate, including its deliberately altered-row negative. `PhysicsGeometryPreparation` uses the native single-thread executor for its short ordered chain. Compare the same source cohort in normal A/B/A windows and require exact replay against the maintained reference before changing its executor. Main-thread schedule self time includes worker waits; do not label the whole self span dispatch overhead. Attribute that child schedule separately from the complete fixed cycle and the native solver. The shared application also configures `FixedPostUpdate` with the native single-thread executor for the surrounding physical commit chain. Attribute that outer schedule separately from `PhysicsSchedule` and geometry preparation. Keep native parallel queries, Modelica worker pools and authored replay checks when comparing executor configurations. When attributing native GPU preprocessing, trace allocation identity rather than only buffer capacity. Bevy's `collect_buffers_for_phase` exchanges per-phase and frame-level buffer cohorts each frame; equal sizes do not mean consecutive bindings agree. Native view groups must be present on current extracted views. Compare actual buffer identities, binding offsets/ranges, layout descriptors, occlusion textures, work modes/counts and bin-job parameters, and measure admission overhead and native rebuild frequency. Pipeline-cache change ticks alone are unsuitable: native queue processing mutably accesses that resource every frame. Preserve native deferred publication and every GPU preprocessing/draw pass. See the current handover for the owned
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub