Profiles and Pipelines¶
Profile structure¶
A timing profile is versioned JSON:
{
"name": "my-profile",
"version": "1.0.0",
"description": "Purpose and target of this profile",
"components": {
"example-link": {
"fixed_latency_ns": 50.0,
"bandwidth_gbps": 100.0,
"packet_rate_mpps": 148.8,
"lanes": 1,
"resource_mode": "overlap",
"evidence": "analytic",
"notes": "State the source of every value."
}
}
}
Unknown component fields are rejected. Each component key becomes its unique name.
Component fields¶
| Field | Type | Meaning |
|---|---|---|
fixed_latency_ns |
non-negative number | Cost paid by every visit |
instruction_rate_mips |
positive number or null | Million guest instructions per second |
clock_mhz |
positive number or null | Component cycles per microsecond |
bandwidth_gbps |
positive number or null | Transfer bit rate |
packet_rate_mpps |
positive number or null | Million packets per second |
compute_tops |
positive number or null | Trillion operations per second |
lanes |
positive integer | Parallel service lanes |
resource_mode |
overlap or serial |
Combine active dynamic terms by maximum or sum |
evidence |
analytic or calibrated |
Result class |
target |
string or null | Required for calibrated components |
calibration_scale |
positive number | Fitted (\alpha) |
calibration_offset_ns |
finite number | Fitted (\beta) |
uncertainty_pct |
non-negative number or null | Declared uncertainty, when justified |
notes |
string | Source, assumptions, and use limits |
Work dimensions¶
A pipeline stage can request:
| Work field | Use |
|---|---|
instructions |
Guest CPU work under an instruction-rate profile |
cycles |
Device, memory, or accelerator architectural cycles |
bytes |
PCIe, link, memory, DMA, or bus transfer |
packets |
Packet-rate-limited NIC or switch work |
operations |
Accelerator arithmetic |
All work values are finite and non-negative. If a stage requests a dimension for which its component has no rate, simulation fails. This prevents accidental zero-cost work.
Overlap versus serial¶
For overlap, active dynamic costs compete and the slowest wins:
[ t=t_0+\max(t_I,t_C,t_B,t_P,t_O). ]
Use this for a resource where throughput is bounded by either packet rate or byte rate, or where compute and memory can overlap.
For serial, active costs add:
[ t=t_0+t_I+t_C+t_B+t_P+t_O. ]
Use this when each requested resource is a distinct sequential phase. If the phases need separate queues or lane counts, model them as separate pipeline stages instead.
Lanes¶
lanes is the number of jobs a component can serve in parallel. Each lane has
an independent availability timestamp. A new event chooses:
- the earliest available lane;
- the lowest lane number when availability ties.
This is deterministic and work-conserving. It does not model priorities or pre-emption.
Pipeline structure¶
{
"stages": [
{
"name": "guest-submit",
"component": "guest-cpu-icount-shift0",
"work": {"instructions": 2500}
},
{
"name": "nic-tx",
"component": "cnuasnic",
"work": {"bytes": 4096, "packets": 4}
},
{
"name": "gpu-kernel",
"component": "cnuasgpu-compute",
"work": {"operations": 1048576}
}
]
}
Stages execute in listed order for each job. Different jobs overlap whenever their required component lanes are available.
Reference profile assumptions¶
cnuas-analytic-v0.json includes both protocol-derived values and illustrative
values:
| Component | Basis |
|---|---|
guest-cpu-icount-shift0 |
QEMU shift 0, one ns per instruction |
pcie-gen5-x16 |
32 GT/s by 16 lanes after 128b/130b encoding, before packet overhead |
bmc-rs485 |
19,200 baud with ten serial bits per eight-bit byte |
| Other bandwidths and latencies | Explicit analytic assumptions in notes |
Copy the profile before changing it. Give the new profile a new name and
version, preserve the source of each value in notes, and do not change
evidence to calibrated without a named target and held-out error report.