<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://open-iov.org/index.php?action=history&amp;feed=atom&amp;title=Performance</id>
	<title>Performance - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://open-iov.org/index.php?action=history&amp;feed=atom&amp;title=Performance"/>
	<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Performance&amp;action=history"/>
	<updated>2026-10-30T19:31:21Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://open-iov.org/index.php?title=Performance&amp;diff=24008&amp;oldid=prev</id>
		<title>WikiBot: 2026-10-30 wiki refresh: goals, GSP, graphics, performance, interfaces</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=Performance&amp;diff=24008&amp;oldid=prev"/>
		<updated>2026-10-30T17:06:16Z</updated>

		<summary type="html">&lt;p&gt;2026-10-30 wiki refresh: goals, GSP, graphics, performance, interfaces&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{About message}}&lt;br /&gt;
&lt;br /&gt;
= Performance =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;'''Scope.''' How Open-IOV's performance is modelled, traced, and planned: the cost structure of the system, the metric set, what is observed today (honestly — there are no published numbers yet), the known gaps with their improvement plans, and the architecture questions the performance work will have to answer. Canonical sources: [https://git.vgpu.io/open-iov.git/tree/docs/05-operations/01-performance-correctness-security.md &amp;lt;code&amp;gt;../docs/05-operations/01-performance-correctness-security.md&amp;lt;/code&amp;gt;] (the measurement contract), [https://git.vgpu.io/open-iov.git/tree/STATE-CURRENT.md &amp;lt;code&amp;gt;../STATE-CURRENT.md&amp;lt;/code&amp;gt;] (the dated snapshot) and [https://git.vgpu.io/open-iov.git/tree/docs/RUNBOOK.md &amp;lt;code&amp;gt;RUNBOOK.md&amp;lt;/code&amp;gt;]; the docs tree wins on disagreement.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Status: 2026-10-30, tree &amp;lt;code&amp;gt;master @ b4930168&amp;lt;/code&amp;gt;. Tags: &amp;lt;code&amp;gt;[live]&amp;lt;/code&amp;gt; measured with working code; &amp;lt;code&amp;gt;[wip]&amp;lt;/code&amp;gt; measurement framework partial; &amp;lt;code&amp;gt;[planned]&amp;lt;/code&amp;gt; designed, not built.&lt;br /&gt;
&lt;br /&gt;
== 1. The performance model ==&lt;br /&gt;
&lt;br /&gt;
The cost structure of a vGPU session splits into four layers, and each is measured separately:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Layer&lt;br /&gt;
! What it costs&lt;br /&gt;
! Representative metric&lt;br /&gt;
|-&lt;br /&gt;
| '''Initialization'''&lt;br /&gt;
| VM boot → driver probe → &amp;lt;code&amp;gt;cuInit&amp;lt;/code&amp;gt;&lt;br /&gt;
| &amp;lt;code&amp;gt;T_init&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''Control plane'''&lt;br /&gt;
| Resource-manager request/reply round trips (objects, controls, memory)&lt;br /&gt;
| RPC latency p50/p99&lt;br /&gt;
|-&lt;br /&gt;
| '''Steady-state data path'''&lt;br /&gt;
| Submission → decode → forward → engine → completion → guest wake-up&lt;br /&gt;
| push overhead; completion latency; kernel throughput&lt;br /&gt;
|-&lt;br /&gt;
| '''Data movement'''&lt;br /&gt;
| Copies between guest memory and device memory&lt;br /&gt;
| copy bandwidth (H2D/D2H/D2D)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Presentation (3D frames) sits on top of the data path, with its own budget (frame pacing, not just frame rate).&lt;br /&gt;
&lt;br /&gt;
Three project rules govern every number:&lt;br /&gt;
&lt;br /&gt;
# '''Correctness before speed.''' A change that makes the vGPU faster but breaks the acceptance corpus does not count.&lt;br /&gt;
# '''Proxy first, optimise by measurement.''' The architecture deliberately prototyped the safe path (emulate the interface, forward the work through the module's own GSP client) before considering a hot path; whether to move the hot path closer to direct submission is a ''measurement decision'', not a design preference.&lt;br /&gt;
# '''No number without methodology.''' Numbers are only quoted with their harness, versions, clocks and warm/cold state, and ideally as a ratio against a same-guest, same-hardware baseline (the A/B method below).&lt;br /&gt;
&lt;br /&gt;
== 2. The metric set ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Metric&lt;br /&gt;
! Definition&lt;br /&gt;
! Why it matters&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;T_init&amp;lt;/code&amp;gt;&lt;br /&gt;
| VM boot → &amp;lt;code&amp;gt;cuInit&amp;lt;/code&amp;gt; returns&lt;br /&gt;
| user-visible startup&lt;br /&gt;
|-&lt;br /&gt;
| RPC latency p50/p99&lt;br /&gt;
| request write → reply visible in the status queue&lt;br /&gt;
| init and management overhead&lt;br /&gt;
|-&lt;br /&gt;
| Push overhead&lt;br /&gt;
| guest submission → engine start (forwarded)&lt;br /&gt;
| steady-state latency&lt;br /&gt;
|-&lt;br /&gt;
| Semaphore completion latency&lt;br /&gt;
| release written → tracker observes&lt;br /&gt;
| per-operation sync cost&lt;br /&gt;
|-&lt;br /&gt;
| Copy bandwidth&lt;br /&gt;
| H2D/D2H/D2D, large and small&lt;br /&gt;
| data-movement quality&lt;br /&gt;
|-&lt;br /&gt;
| Kernel throughput&lt;br /&gt;
| kernels/second for a fixed workload&lt;br /&gt;
| launch overhead&lt;br /&gt;
|-&lt;br /&gt;
| Multi-tenant fairness&lt;br /&gt;
| per-tenant progress under contention&lt;br /&gt;
| isolation quality&lt;br /&gt;
|-&lt;br /&gt;
| Frame pacing&lt;br /&gt;
| inter-frame deltas under load&lt;br /&gt;
| graphics smoothness (p95 is the budget)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 3. How performance is traced today ==&lt;br /&gt;
&lt;br /&gt;
* '''Host-side telemetry.''' The module timestamps its own work: per-run counters in the kernel log (accepted / failed / retried / refused work, decode outcomes, forward outcomes), &amp;lt;code&amp;gt;trace_printk&amp;lt;/code&amp;gt;/tracepoints at dispatch entry/exit for distributions, and counter surfaces readable through the kernel's tracing and debug filesystems. Module parameters exist for targeted probes during bring-up — they are debug surfaces, not configuration ([[Interfaces and Stability|&amp;lt;code&amp;gt;Interfaces-and-Stability.md&amp;lt;/code&amp;gt;]]).&lt;br /&gt;
* '''Guest-side instruments.''' The guest test clients print their own acceptance ''and'' timing lines (they are the ground truth for what the application observed); guest-side kernel probes and ptrace tools attribute driver-side waits when a client stalls.&lt;br /&gt;
* '''The A/B harness.''' Every measurement runs twice on the same machine and preferably the same boot: '''A''' = the workload on the physical GPU with the stock driver; '''B''' = the identical workload in the guest on the emulated vGPU. Results are reported as '''B/A ratios'''; warm and cold, with variance and run counts. One variable at a time; the harness is published so results are comparable.&lt;br /&gt;
* '''Offline tools — with a hard boundary.''' The risc-v-gsp-rm-debugger workbench models ''instruction semantics and memory behaviour only''; it makes '''no timing claims''' (its fidelity levels explicitly exclude time and concurrency). Timing questions are answered on hardware, with instrumentation.&lt;br /&gt;
* '''The evaluation ladder.''' Performance is only meaningful from the ''execution'' rung upwards: initialization → runtime start → execution → sustained → multi-tenant. Claims are made per rung, never across it.&lt;br /&gt;
&lt;br /&gt;
== 4. Where it stands today (honest) ==&lt;br /&gt;
&lt;br /&gt;
'''There are no published performance numbers yet.''' The framework above is the contract; the first formally recorded measurements are scheduled, not done. What ''is'' observed today, clearly labelled as internal observation rather than benchmark:&lt;br /&gt;
&lt;br /&gt;
* '''Forwarded CUDA launch latency is on the order of hundreds of milliseconds''' end-to-end on the development setup (one ten-client arc measured p50 ≈ 650 ms). This is the dominant known cost, dominated by the submission trap → decode → forward chain and by polled completion waits — not by the engine itself.&lt;br /&gt;
* '''Data movement is verified correct, not yet measured for throughput''': copies through the forwarded path round-trip byte-exact; the A/B bandwidth runs (the &amp;lt;code&amp;gt;nvbandwidth&amp;lt;/code&amp;gt;-class suite) are pending.&lt;br /&gt;
* '''Graphics frame delivery is far below interactive rates''' in the recorded pipeline runs — the defined target is 60 fps ''sustained with no forcing'' ([[Graphics Execution|&amp;lt;code&amp;gt;Graphics-Execution.md&amp;lt;/code&amp;gt;]]); today's frame numbers come from development instrumentation and are explicitly not a benchmark.&lt;br /&gt;
* '''Initialization is functional''': the backend's GSP boot reaches init-done in about a second on the reference hardware; &amp;lt;code&amp;gt;T_init&amp;lt;/code&amp;gt; as a guest-visible measurement has not been taken.&lt;br /&gt;
* '''The software path is already cheap where it is work-shaped''': decoded memory operations execute at host memory speed; control-plane replies are produced inline in the emulation thread; the expensive parts are the ''control-heavy'' structures (per-push passes, scanning, polling).&lt;br /&gt;
&lt;br /&gt;
== 5. Observed gaps and the plan for each ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Gap&lt;br /&gt;
! Observation&lt;br /&gt;
! Plan&lt;br /&gt;
|-&lt;br /&gt;
| Forwarded-launch latency&lt;br /&gt;
| hundreds of ms (internal); dominated by the multi-step forward chain and completion polling&lt;br /&gt;
| instrument the distribution end to end; reduce per-push passes; move completion to event-driven paths; re-measure per step&lt;br /&gt;
|-&lt;br /&gt;
| Completion latency&lt;br /&gt;
| releases are detected by polling the engine/guest memory&lt;br /&gt;
| prefer engine-authored release paths already used by verified launches; doorbell/event wake-ups instead of periodic scans where possible&lt;br /&gt;
|-&lt;br /&gt;
| RPC dispatch cost&lt;br /&gt;
| all management funnels through one emulation thread&lt;br /&gt;
| build the RPC round-trip microbenchmark first; batch and prioritise; reduce wake-ups&lt;br /&gt;
|-&lt;br /&gt;
| Scanning overhead&lt;br /&gt;
| per-pass discovery/scan work (guest RAM, shadow apertures) exists for correctness while registrations are incomplete&lt;br /&gt;
| convert discovery to registered/learned state so per-pass cost scales with ''work'', not with memory size&lt;br /&gt;
|-&lt;br /&gt;
| BAR0 shadow reads&lt;br /&gt;
| uncached to the guest, as MMIO must be; bulk reads would be slow&lt;br /&gt;
| if a consumer bulk-reads, introduce cache-safe sub-regions rather than a slower guest&lt;br /&gt;
|-&lt;br /&gt;
| Memory-model gap&lt;br /&gt;
| guest VRAM is backed by host RAM today&lt;br /&gt;
| real VRAM backing is a target; DMA-heavy workloads are not representative until it exists&lt;br /&gt;
|-&lt;br /&gt;
| Graphics frame path&lt;br /&gt;
| far below 60 fps; forcing/diagnostic assistance excluded by the target definition&lt;br /&gt;
| the graphics milestone ladder: natural completions with no mirror, then measure pacing&lt;br /&gt;
|-&lt;br /&gt;
| Multi-tenant fairness&lt;br /&gt;
| two guests coexist; fairness under load is untested&lt;br /&gt;
| define the fairness metric, run two-VM contention, then add scheduling policy&lt;br /&gt;
|-&lt;br /&gt;
| Initialization&lt;br /&gt;
| functional but unmeasured&lt;br /&gt;
| take &amp;lt;code&amp;gt;T_init&amp;lt;/code&amp;gt; and the reply-fidelity tail as the next control-plane measurement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 6. The improvement programme ==&lt;br /&gt;
&lt;br /&gt;
# '''Build the microbenchmarks first''' — the four the measurement contract names: RPC round-trip, MSI-X delivery latency, BAR0 shadow read latency, and doorbell-polling cost. These attribute overhead to components before any optimisation.&lt;br /&gt;
# '''Run and publish the A/B corpus''' — the canonical suite (vector-add, SGEMM, copy bandwidth, a GL frame-rate app, a framework op loop) with the contract's pass criteria (e.g. ≥95% B/A for compute, ≥90% for GL and framework loops) and full environment capture.&lt;br /&gt;
# '''Optimise the observed hot structures''' — fewer per-push passes, batched decode, event-driven completion, shadow-window reuse — each as an A/B change with its numbers kept.&lt;br /&gt;
# '''Evaluate the hot-path placement decision''' — keep the module as a GSP client proxy, or move submissions closer to direct channels — using the measured budgets as the criterion.&lt;br /&gt;
# '''Publish the first graphics measurement''' — 60 fps sustained, no forcing, p95 inter-frame pacing — as the first end-to-end performance claim.&lt;br /&gt;
# '''Then multi-tenant''': define fairness, measure it, and only then claim it.&lt;br /&gt;
&lt;br /&gt;
== 7. Architecture areas that may need to improve — open questions ==&lt;br /&gt;
&lt;br /&gt;
These are the structural questions the performance programme exists to close:&lt;br /&gt;
&lt;br /&gt;
* '''One ordered workqueue, one in-flight request.''' The current design serialises forwarded work for ordering safety. Is that a throughput ceiling for multi-channel/multi-launch workloads, and how much pipelining is possible without weakening the ordering guarantees the guest observes?&lt;br /&gt;
* '''Per-pass scanning vs registered state.''' Ring/USERD discovery, content scans and shadow diffs are correctness mechanisms; can they be replaced (or narrowed) by registrations learned on first sight, so steady-state cost does not scale with aperture size?&lt;br /&gt;
* '''Completion publication machinery.''' Which of poll, engine-authored release, notifier and event paths should carry the steady state — and what is the p99, not just the median?&lt;br /&gt;
* '''MMIO trap frequency.''' Doorbells and shadow writes pay a VM-exit cost; which guest patterns produce the most traps, and can they be coalesced or served with less work?&lt;br /&gt;
* '''The transport itself.''' Guest-system-memory message queues plus doorbells are deliberately conservative; would a shared-ring fast path change the budget materially?&lt;br /&gt;
* '''Hot-path placement.''' Proxy through the module's own GSP session vs moving hot submissions closer to the hardware — decided by the A/B numbers, not by preference.&lt;br /&gt;
* '''Multi-tenant scheduling.''' Time-slicing exists only as a default; the fairness policy (and MIG-backed partitioning where available) is a design area, with fairness measurements defined before the claim.&lt;br /&gt;
* '''Fidelity boundary.''' The offline simulator can never answer timing or concurrency questions; the performance programme therefore owns all timing claims, and no timing claim may cite a simulator session.&lt;br /&gt;
&lt;br /&gt;
== 8. Related pages ==&lt;br /&gt;
&lt;br /&gt;
* [[Interfaces and Stability|&amp;lt;code&amp;gt;Interfaces-and-Stability.md&amp;lt;/code&amp;gt;]] — which surfaces are contracts and which are free to change.&lt;br /&gt;
* [[The Execution Frontier|&amp;lt;code&amp;gt;Execution-Frontier.md&amp;lt;/code&amp;gt;]] — the compute path whose latency this page budgets.&lt;br /&gt;
* [[Graphics Execution|&amp;lt;code&amp;gt;Graphics-Execution.md&amp;lt;/code&amp;gt;]] — the 60 fps target and its milestone ladder.&lt;br /&gt;
* [[Physical GPU Backend and Guest Wiring|&amp;lt;code&amp;gt;Physical-GPU-Backend.md&amp;lt;/code&amp;gt;]] — the backend the work is forwarded to.&lt;br /&gt;
* [[The Host Module (vgsp.ko)|&amp;lt;code&amp;gt;Host-Module.md&amp;lt;/code&amp;gt;]] — the module whose threads, queues and scans carry the costs above.&lt;br /&gt;
* [https://git.vgpu.io/open-iov.git/tree/docs/05-operations/01-performance-correctness-security.md &amp;lt;code&amp;gt;../docs/05-operations/01-performance-correctness-security.md&amp;lt;/code&amp;gt;] — the measurement contract: ladder, metrics, A/B method, microbenchmarks, targets.&lt;/div&gt;</summary>
		<author><name>WikiBot</name></author>
	</entry>
</feed>