ConceptioArchivearXiv CS
arXiv CSopen access

Microflow: Microarchitectural Causal Observability for Deep Cross-Layer Analysis and Optimization

Unknown · 2026 · arxiv_cs
arXiv CS · Papers · License: Open Access · 2026
Open Source ↗Direct PDF ↓
softwarearchitecturesoftwareengineeringtesting
software engineering, software architecture, testing

Microflow: Microarchitectural Causal Observability for Deep Cross-Layer Analysis and Optimization Saber Ganjisaffar

University of California, Riverside Riverside, CA, USA [email protected]

Chengyu Song

University of California, Riverside Riverside, CA, USA [email protected]

Unlike post-silicon profilers [1, 2, 4, 8, 12, 14, 16, 20, 22, 26, 28], simulators offer a class of observability that real hardware fundamentally cannot provide: full access to internal pipeline state, cycle-accurate visibility into speculative and wrong-path execution that hardware counters cannot attribute or sample, and the freedom to instrument, modify, or rerun any aspect of the design. This makes simulation indispensable for the iterative loop of microarchitectural exploration: observe a bottleneck, modify a design parameter, and measure the effect, all before any silicon exists. Simulator-based analysis is therefore a qualitatively different problem from post-silicon software profiling: tools such as Intel VTune [14] and AMD 𝜇Prof [2] can only help software engineers optimize programs on fixed, shipped hardware through sampling-based PMU profiling. The problem simulators address is upstream and broader, serving architects evaluating candidate microarchitectures, compiler engineers assessing how code transformations interact with hardware structures, and researchers reasoning about hardware-software co-design tradeoffs. In all of these cases, the shared need is the same: understanding not just what a microarchitecture does, but why, at a level of causal detail that only a cycle-accurate simulator can provide. Despite this rich observability, the analytical infrastructure built on top of simulators has not kept pace. Today’s simulation workflows surface performance data as flat event logs and aggregate statistics. These outputs describe what happened, but not why: they record that a dispatch stall occurred, but not which prior event caused it; that the instruction queue was full, but not which instructions filled it or what sequence of instructions caused them. Recovering causal structure from these outputs requires manually correlating logs across pipeline stages, abstraction layers, and hundreds of cycles, a process that relies on imprecise heuristics such as temporal proximity or address matching rather than groundtruth causal links, and that scales poorly as microarchitectural complexity grows or the problem under investigation changes. The fundamental problem is not a lack of potential observability: simulators expose every internal state transition needed to answer these questions. The problem is the absence of a standard instrumentation and representation layer that captures events and the causal relationships between them, leaving architects to choose between aggregate statistics or the labor-intensive construction of custom analysis scripts for each new performance question. To make this concrete, consider an architect observing that 40% of cycles are lost to instruction dispatch stalls, with analysis classifying the bottleneck as Backend-Core bound. The natural prescription is structural: widen the issue window or increase the size of the reorder buffer. What the aggregate statistics cannot reveal is that the stall is not a capacity problem at all. The queue is clogged with wrong-path instructions from a recent branch mispredict that will

arXiv:2607.13184v1 [cs.AR] 14 Jul 2026

Abstract Existing architectural simulators expose aggregate metrics or raw event traces, but fail to reveal the complex interactions among microarchitectural events and the relationship between the program and the resulting microarchitectural outcomes. As a result, architects can observe performance symptoms and overall behavior, but cannot systematically attribute them to root causes across abstraction layers. This paper introduces Microflow, a microarchitectural observability framework that elevates causality to a first-class analytical object. Microflow transforms execution traces into a structured representation, the Microflow Intermediate Representation (MFIR), which explicitly captures dependencies across software semantics, instructions, pipeline events, and hardware resources. By unifying instruction execution, resource contention, and program semantics within a single graph, MFIR enables direct traversal from observed events such as stalls to their underlying causes. We show that this representation enables qualitatively new forms of analysis, paving the way for next-generation microarchitectural observability and automated root-cause analysis of performance bottlenecks. Microflow precisely attributes stalls to their originating events, reveals previously unobservable phenomena, and enables exact critical-path decomposition of execution time through counterfactual analysis. These capabilities enable systematic reasoning about complex hardware–software interactions that are opaque to existing tools. By making microarchitectural causality explicit and queryable, Microflow provides a new foundation for performance analysis and hardware–software co-design. We demonstrate Microflow on two SPEC CPU 2017 benchmarks, uncovering bottlenecks invisible from aggregate symptoms: a self-reinforcing RAS corruption cascade in 541.leela_r that inflates the true misprediction cost by 29%, and cross-loop-iteration contention in 505.mcf_r.

Keywords Microarchitecture, Performance Analysis, Observability, Causality Analysis, HW/SW Co-Design.

1

Nael Abu-Ghazaleh

University of California, Riverside Riverside, CA, USA [email protected]

Introduction

Architectural simulation is the primary workbench of pre-silicon hardware design. Before a microarchitecture reaches fabrication, architects and compiler engineers rely on cycle-accurate simulators [6, 9, 15, 17–19, 23–25, 27, 29] to evaluate design decisions, assess hardware-software co-design trade-offs, and identify performance bottlenecks that would otherwise only surface after tape-out. Conference’17, Washington, DC, USA 2026. ACM ISBN 978-x-xxxx-xxxx-x/YYYY/MM https://doi.org/XXXXXXX.XXXXXXX 1

Conference’17, July 2017, Washington, DC, USA

Saber Ganjisaffar, Chengyu Song, and Nael Abu-Ghazaleh

be squashed within a few dozen cycles. The correct intervention should be targeting speculative fetch throttling, an entirely different layer of the microarchitecture. Without causal visibility, the wrong diagnosis leads to the wrong design decision. This class of bottlenecks is not unique. Modern out-of-order processors are rich with causal interactions that cross abstraction layers and manifest far from their origin. A single cache eviction triggered by a cold access can displace a hot line that is demanded thousands of cycles later, linking two distant instructions through an invisible causal arc. A long-latency load stalled at the head of the Reorder Buffer (ROB) drains commit bandwidth and starves the entire pipeline, yet the ROB-full symptom carries no record of which memory access is responsible or what data dependency chain led there. In each case, the measurable symptom and its root cause are separated in time, pipeline stage, and abstraction layer. Aggregate statistics collapse these chains into scalar counts; the relationships between events are discarded rather than recorded. A representation that makes these relationships explicit and traversable is precisely what current simulation workflows lack. Figure 1 contrasts the two analysis paths: current methodologies observe aggregate symptoms and treat bottlenecks as independent, while Microflow traces causal dependencies to attribute bottlenecks to their shared root cause and derive targeted fixes. We present Microflow, a microarchitectural performance analysis framework that captures the causal structure as a first-class object during simulation. The foundation of Microflow is Microtracer, a lightweight instrumentation library that annotates simulator events with two identifiers at the point of occurrence: a flow ID and a resource ID. Flow is a core concept in Microflow, which represents the complete lifecycle of a dynamic entity such as an instruction or cache transaction across pipeline stages and memory subsystem. And the resource ID records contention over a shared microarchitectural structure such as cache lines or Miss Status Handling Register (MSHR) entries. By preserving both the partial order of events within each flow and the global ordering across flows with respect to simulation time and object identity, Microtracer encodes causal relationships at event capture time without requiring post-hoc inference. A trace compiler then assembles these annotations into the MicroFlow Intermediate Representation (MFIR), a unified causal graph encoding four classes of relationships: sequential event ordering within flows, cross-flow dependencies, resource contention edges over shared microarchitectural structures, and semantic edges linking hardware events to their source-level program origins. An Analysis Query Engine sits on top of the MFIR, exposing it as a collection of typed, queryable relations over columnar storage. This design allows performance questions to be expressed as declarative queries over the causal graph rather than custom parsing scripts. It also enables reusable analysis modules that encode recurring performance studies as structured passes over the same representation, covering stall attribution, throughput breakdowns, and cross-layer root-cause summaries. As a concrete example, we implemented a Top-down Microarchitectural Analysis (TMA) [30] implemented as an MFIR analysis module. We then used it as a drop-in replacement of coarse PMU-based estimates, with exact per-instruction measurements derived from lifecycle records, and

Current Methodologies

MicroFlow Framework

Aggregate Symptoms (the "What")

Causal Attribution (the "Why")

Application Simulator/PMU Counters (Aggregate Metrics) Observed Aggregated Symptoms Bottleneck A Bad Speculation (e.g. ↑ MPKI)

Bottleneck B Backend Mem (e.g, ↑ L2 miss rate)

?

Application MicroFlow Extracting Fine-Grained Symptoms Causal Dependency Analysis Pipeline event X (e.g. misprediction)

Wrong-path side effects

Temporal + Casual Correlation

Downstream stall for event Y

Treated as independent no causal connection

Optimization Path Attack each bottleneck separately May miss shared root cause Suboptimal or infeasible fix

Bottleneck B attributed to root cause of A true cost of X = A + B (not independent) Targeted Optimization Attack shared root cause directly feasible fix, maximum IPC gain

Figure 1: Current methodologies observe aggregate symptoms without causal structure, leaving root causes and crosslayer interactions undetected. Microflow makes them directly observable through causal dependency tracing, enabling targeted optimization. produced per-function and per-PC bottleneck breakdowns at a resolution fundamentally unachievable from hardware counters alone. Section 4 presents two case studies on SPEC CPU 2017 benchmarks. For 541.leela_r, our TMA reports 47.7% Bad Speculation and prescribes better branch prediction, yet the MFIR reveals a self-reinforcing RAS corruption cascade invisible to existing tools, inflating the true misprediction cost by 29% and decomposing into three actionable causal mechanisms projecting +21% IPC. In summary, this paper makes the following contributions: • We identify the absence of causal structure in simulation workflows as the fundamental barrier to root-cause performance analysis in pre-silicon design. • We present Microflow, a framework that integrates causal instrumentation, representation, and analysis, enabling rootcause diagnosis through structured graph traversal. • We present Microtracer and the MFIR, an instrumentation library and causal graph representation that capture and encode inter-event relationships across instruction flows, resource contention, and program semantics as first-class objects. • We present an Analysis Query Engine that exposes the MFIR as typed, declarative relations, enabling systematic microarchitectural performance studies and reusable analysis modules over a single shared representation. • We apply Microflow to real-world benchmarks, uncovering three causally distinct performance phenomena invisible to existing tools and deriving targeted fixes.

2

Microflow Framework Design

Existing microarchitectural approaches can be categorized into: (1) Post-silicon profiling; and (2) Pre-silicon simulation. Neither of these approaches can simultaneously provide microarchitectural fidelity, precise semantic attribution, causal cross-layer visibility, and scalable analysis. Post-silicon profiling [1, 2, 4, 8, 12, 14, 16, 20, 22, 26, 28] offers rich semantic context and established methodologies 2

Microflow: Microarchitectural Causal Observability for Deep Cross-Layer Analysis and Optimization

Shadow Registries

Component 1 e.g., fetch stage

Flow and Resource Hash Tables

MTRACE() MTRACE()

... ...

MTRACE()

Sim Thread

Dynamic Event Schema Generator Rule Lookup

Thread-Local Caches KEY

Component N

Trace Compiler

Analysis Engine

Async Worker Thread

Typed Vertex Decoder

Analysis Modules

Polls Periodically Adaptive Batching

Dependency Edge Gen.

MicroTracer

Sim Thread

FID, RID

Event Record

Correlation Rules

- CTX(CYCLE, PC,...) - PARAMS (compact) - FID - RID - Event ID

Event Registry

Per-Thread Event Submission

Resolve Event Type and ID

Event Record - CTX(CYCLE, PC,...) - PARAMS - KEY - FID - RID

Event Schemas

Stall Attribution

Flow/Resource Builder

Structural Localization

SW Semantic Linker

Event Timeline Vis.

Inst. Lifecycle Builder Custom Queries

Event Batch Buffer Enqueue Submission Queue

Symptom Identification

...

Arch. Simulator

Conference’17, July 2017, Washington, DC, USA

Dequeue Bulk

Trace Writer

Analysis API Router Trace File

Binary Analysis DB

MFIR

MFIR Loader

Query Engine

Figure 2: Overview of the Microflow Framework. such as Intel’s Top-Down Microarchitectural Analysis (TMA) [30] that only produce aggregate metrics with no causal links between events. They cannot trace how microarchitectural effects propagate across pipeline stages, and are confined to fixed, already-fabricated hardware. Pre-silicon simulation [6, 9, 15, 17–19, 23–25, 27, 29] provides full state visibility and design freedom, but exposes no standard causal representation or semantic attribution. AI-driven frameworks automate exploration but inherit the observability limits of their inputs. Microflow addresses this gap by introducing a causal, cross-layer representation of microarchitectural execution that not only enables new classes of analyses directly, but can also assist methodologies such as AI-driven exploration by providing the causally attributed context. The Microflow framework is designed to bridge the semantic gap between raw simulator event streams and high-level performance insights. Its primary objective is to automatically extract the causal structure of execution, enabling the identification of cross-layer interactions that give rise to specific microarchitectural behaviors. Microflow achieves this through four tightly integrated components as shown in Figure 2: (1) An architectural simulator; (2) Microtracer, an asynchronous event tracing mechanism; (3) a trace compiler that constructs the MFIR as the central analytical abstraction; and (4) a tiered analysis engine that facilitates efficient and scalable querying and automatic analysis over the MFIR. The following sections examine each of these four components, outlining their design and implementation.

2.1

I/O from the critical path, (2) a declarative domain model that separates event semantics from correlation policy, and (3) shadow registries that assign stable identifiers at capture time, eliminating fragile post-hoc heuristic-based reconstruction. 2.1.1 Asynchronous Event Tracing. We next describe the event capture and submission path. Simulation producer threads execute instrumentation at fixed sites. Each submission carries logical time or ordering information (e.g., cycle count, program counter, and sequence identifiers where needed), an event type, a list of parameters for downstream analysis, and, when required, handles to live model objects such as instructions, memory requests, queue entries, or cache lines. When multiple in-flight instructions share the same PC or when speculative execution produces concurrent live objects, scalar properties alone cannot disambiguate their records. Correlation therefore uses simulator object handles as opaque, addressstable keys. Declarative rules (Section 2.1.2) define how these keys map to flow and resource columns, while Section 2.1.3 describes the registries that maintain these bindings. Once correlation fields are populated, the event is enqueued into a bounded queue. A consumer thread assigns compact numeric event identifiers, batches records, and writes Parquet under a single physical schema shared across many logical event types. Producers never perform column encoding or filesystem I/O. When the queue is full, policy selects blocking or lossy behavior, trading latency or completeness for a fixed memory bound. As a result, producer overhead is limited to submission and synchronous correlation, while formatting and I/O costs are isolated to the consumer thread. 2.1.2 The Event Domain Model. Microtracer separates what is logged from how events are correlated. Both are specified outside the tracer core as declarative data. Event definitions form the public vocabulary: each event specifies a name, an ordered parameter list, and types. This contract determines how decoders and analysis tools interpret each row, including which fields encode addresses, sequence numbers, or other operands. Correlation rules reference these event definitions and specify which registry actions execute at each instrumentation site, including allocate, lookup, link, and free, as well as which parameters supply the relevant handles. These rules execute at capture time alongside the shadow registries. Because event definitions and correlation rules are independent artifacts, event semantics and correlation policies can evolve without modifying the tracing pipeline. Different simulators

Microtracer

At the core of the Microflow framework is Microtracer, a modular event-tracing layer integrated into the architectural simulator as a shared library. Microtracer records a faithful stream of microarchitectural activity while decoupling trace serialization and disk I/O from simulation progress. Producers perform correlation synchronously at capture time, assigning flow and resource identifiers before enqueue, and hand off the encoded record to a background consumer responsible solely for batching and I/O. Correlation is never deferred to the consumer, ensuring registry operations respect simulation order and that handles are resolved before the simulator reclaims their storage. Microtracer follows three design principles: (1) asynchronous handoff of encoded records to remove 3

Conference’17, July 2017, Washington, DC, USA

RID

FID 100

Fetch

100

Decode

100

100

Exec

L1D Access

ALLOC store inst_A

Shadow Registries

LOOKUP for inst_A

Flow Registry key FID inst_A 100 pkt_A 100

LOOKUP for inst_A

inst_B pkt_B

LINK parent inst_A child pkt_A

34

100

L1D Miss

100

MSHR Alloc

100

Commit

ALLOC_SHARED store mshr_A

FREE remove inst_A

mshr_A

ALLOC store inst_B

FID Fetch

RID

call graph

CALLS_INTO

function

CALLS_INTO

FID 100 200

LINK parent inst_B child pkt_B

BACK_EDGE

Software Semantic Layer

SUCCESSOR

basic block

200

function

200 200

Shared Resource Registry key

LOOKUP for pkt_A

Saber Ganjisaffar, Chengyu Song, and Nael Abu-Ghazaleh

CONTAINS

CONTAINS

loop

CONTAINS

basic block

CONTAINS

basic block

Instruction

CAUSES

Microarchitecture Layer

FID = f1

L1D Access

200

L1D Miss

200

MSHR Coalesced

200

fetch

decode

rename

issue

execute

writeback

commit

RID 34

LOOKUP for pkt_B JOIN_SHARED search mshr_A

FREE remove inst_B

FID = f2

Commit

SPAWNS

34

I$ request

miss

Resource Layer MSHR entry

200

RID = R1

Figure 3: Two concurrent loads: distinct flow IDs; a shared resource ID for one MSHR entry both flows contend for.

MSHR alloc

ACQUIRE

ROB entry RID = R2

line fill

I$ response

ACQUIRE

IQ entry RID = R3

...

cache line RID = R4

Figure 4: The MicroFlow Intermediate Representation (MFIR) as a layered structure. Software vertices (functions, basic blocks, instructions) connect to microarchitectural events and instruction lifecycles, which in turn interact through shared hardware resources such as MSHRs, ROB entries, and cache lines.

or subsystems can provide distinct domain packages. The trace itself stores compact numeric event identifiers under a uniform physical schema, while the domain specification maps these identifiers back to their semantic definitions.

its first tenant. Instruction B follows the same path (FID = 200, child pkt_B); its subsequent cache miss triggers Join_Shared, which locates the already-allocated mshr_A entry and appends FID = 200 as a second tenant under the same RID = 34. Both flows are joined at the MSHR in the trace at capture time, with no post-hoc reconstruction. Free at each commit removes the respective instruction handle, releasing the flow registry entry and permitting handle reuse without aliasing. The resulting trace directly encodes both causal chains and shared-resource contention, enabling downstream analysis to reason about coalescing, contention ordering, and completion without re-deriving these relationships from timing or address heuristics.

2.1.3 Shadow Registries and Causal Correlation. Shadow registries are auxiliary lookup structures maintained alongside, but separate from, simulator state. They store handle-to-identifier mappings required for joins in the trace and do not own modeled objects or replicate full microarchitectural state. On each event capture, the instrumentation thread evaluates correlation rules, updates the registries, and writes flow and resource identifiers into the trace record before enqueue. Performing correlation at capture time is essential. Deferring it to the consumer would violate ordering constraints among registry operations (e.g., allocate before lookup, parent registration before child link, and free before handle reuse), allow queue order to diverge from simulated causality under parallel producers, and risk resolving handles after the simulator has reclaimed their storage. Microtracer maintains two registries. The flow registry assigns one identifier per causal chain, typically spanning a dynamic instruction’s lifetime across pipeline stages and its associated memory activity. It treats handles strictly as opaque keys in ALLOC, LOOKUP, LINK, and FREE operations. Epoch or generation counters prevent aliasing when addresses are reused, and policy may supply a thread-local default when no handle is present. The shared-resource registry captures interactions where multiple flows converge on a common structure, such as cache lines or MSHR entries. It maps resource handles to a resource identifier and tracks the set of flows associated with that identifier, grouping contending chains under a single RID without requiring address matching or timestamp inference. A single event may carry both a flow identifier and a resource identifier when it belongs to one causal chain and simultaneously involves a shared structure. Figure 3 traces both operations step by step. Instruction A is Alloc’d at fetch (FID = 100); Decode and Exec each Lookup the same key, propagating the identifier forward. At the L1D access, a Link rule spawns child flow pkt_A (FID = 100), recording that this cache request belongs to instruction A’s chain. On a cache miss, Alloc_Shared on mshr_A creates RID = 34 and records FID = 100 as

2.2

MicroFlow Intermediate Representation

The MicroFlow Intermediate Representation (MFIR) is the structured representation produced by compiling raw microarchitectural traces generated by Microtracer. The Trace Compiler decodes recorded events, preserves correlations captured at trace time, and reconstructs an explicit account of execution in the modeled microarchitecture. Conceptually, MFIR is a heterogeneous, typed graph: vertices are drawn from a small set of kinds, and edges represent a fixed set of dependency classes, each encoding a specific relationship. MFIR is stored using a columnar, relational layout suitable for analytical engines or graph databases at scale. A key design principle of MFIR is explicitness: any dependence observed during execution is materialized as a typed edge. As a result, analysis operates directly on these edges, avoiding reliance on implicit inference from timestamps, program counters, or address matching. MFIR is grounded in simulation semantics. It captures the partial order defined by the microarchitectural model and the dependencies reconstructed during compilation. This separation mirrors the role of intermediate representations in compilers: As a raw binary encodes program behavior completely yet requires lifting to an IR before analyses can share results, a raw trace is a correct but implicit record that MFIR exposes in reusable, typed form. Consequently, 4

Microflow: Microarchitectural Causal Observability for Deep Cross-Layer Analysis and Optimization

downstream analyses target MFIR directly, eliminating the need for repeated, heuristic-driven parsing of raw traces.

decodes each raw record into uniformly typed event vertices with named attributes; (3) materializes the dependency edges from flow structure, spawn relationships, and shared-resource lifetimes; (4) assembles instruction-level summary vertices by aggregating stagelocal events on each instruction flow; (5) incorporates speculationrelated metadata so wrong-path work can be separated in queries; and (6) links semantic vertices to hardware events through addressbased attribution. During this compilation pass, the compiler uses the aggregation of stage-local events to construct a detailed instruction lifecycle table that tracks the progression of every dynamic instruction across pipeline stages. Conceptually, this mirrors the Per-Instruction Cycle Stacks (PICS) of TEA [11] and DIP [5]. However, the MFIR compiler, because it processes the complete event stream without statistical sampling, the resulting table provides exact and cycleaccurate records rather than statistical estimations. Furthermore, whereas hardware profilers are inherently restricted to observing committed instructions—typically capturing data only at discrete dispatch [5] or commit [11] boundaries—the trace compiler captures full microarchitectural states, recording transient operations and wrong-path speculative executions. Later automated analysis modules directly query this lifecycle table to automatically identify and localize performance bottlenecks based on user defined patterns, relying on complete Per-Instruction Cycle Stacks and stall attributions not available from physical hardware alone.

2.2.1 Vertices and Layers. MFIR organizes vertices into three primary layers, microarchitectural, resources, and software, as illustrated in Figure 4. The microarchitectural layer unifies fine-grained events with instruction-level summaries. Each simulator event is represented as a vertex annotated with simulation time, program context (when applicable), decoded attributes, and capture-time correlation metadata, forming the ground-truth record of execution. In parallel, each instruction lifecycle is represented by a summary vertex capturing stage timings and stall behavior, and is explicitly linked to its constituent events. Exposing both granularities within the same representation to move between event-level causality and instruction-level performance without repeated reconstruction. The resource layer models shared hardware structures, such as cache lines, MSHRs, and queue entries, as first-class vertices. Multiple concurrent flows may reference the same resource, and MFIR encodes this sharing explicitly, allowing contention and completion to emerge directly from graph structure. When program information is available, the software layer introduces vertices for software semantics such as functions, control-flow constructs, call graphs, and static instruction sites. Attribution edges connect these to microarchitectural vertices, enabling cross-layer queries without repeated symbol resolution. 2.2.2 Dependencies and happens-before. Edges in MFIR are typed, distinguishing qualitatively different forms of interaction rather than collapsing all relations into a single abstraction. The representation captures: ordering along a single hardware flow (the spine of one dynamic chain through the pipeline or memory system); creation or spawning of a child flow from a parent (for example, an instruction’s request becoming a distinct cache or bus-side activity); waiting and synchronization on shared resources (who blocked, who was satisfied when a structure was released); cross-chain dependences that name how distinct flows interact (instruction-side versus packet-side versus buffering structures); invalidation of speculative work when the model squashes wrong-path execution; and, when enabled, software-to-hardware attribution from semantic vertices to events. This structure enables semantic precision in analysis and defines a simulation happens-before relation over events. An event happens-before another if a directed path of typed dependencies connects them. Within a single flow, ordering edges typically induce a total order; globally, the relation is partial, preserving concurrency until flows interact via resources or explicit links.

2.3

Conference’17, July 2017, Washington, DC, USA

2.4

Analysis Engine

The analysis engine serves as the primary interface for mining the MFIR. The engine exposes the full structural and temporal record in the execution graph through a unified relational abstraction. This allows researchers and AI tools to express arbitrary microarchitectural analyses using declarative queries. The framework empowers architects to rapidly isolate specific instruction lifecycles, filter distinct hardware dependency edges, and query localized temporal windows across large traces, making the event stream an interactive, cross-layer analysis and debugging environment. The analysis engine relies on a typed relational schema and standard SQL queries, which makes it amenable to integration with user developed analyses, and eventually AI agents. The declarative nature of the MFIR vocabulary was designed to ease eventual integration with large language models. An architect can leverage natural language prompts to instruct an AI agent to automatically generate, execute, and interpret the required SQL queries. This capability significantly lowers the barrier to entry for cross-layer microarchitectural debugging, allowing researchers to rapidly iterate on performance hypotheses and automatically synthesize explanations for obscure microarchitectural behaviors without requiring deep expertise in the underlying trace schema. Beyond ad-hoc queries, the engine also provides a programmatic API to build reusable, automated analysis modules. These modules encode recurring performance questions, such as throughput breakdowns, stall attribution, and well-defined cross-layer diagnostics, as standardized analysis passes over the MFIR. This modular architecture directly mirrors modern software compilers, where independent analysis passes operate seamlessly over a standardized

Trace Compiler

The trace compiler turns Microtracer’s raw columnar trace into MFIR. Like a compiler middle end, it consumes a complete but implicit log and produces a typed, versioned IR for downstream uses. Its inputs are the Microtracer’s output trace (with capture-time correlation already embedded) together with the declarative event domain specifications that define the event vocabulary, parameter layouts, and how runtime correlation is to be interpreted. Optionally, a binary-analysis artifact supplies symbols and debug metadata for the software layer of MFIR. The compiler runs as a staged pipeline: it (1) validates the domain against the trace metadata; (2) 5

Conference’17, July 2017, Washington, DC, USA

MFIR

Saber Ganjisaffar, Chengyu Song, and Nael Abu-Ghazaleh

“memory bound.” For each ranked PC it also selects a representative worst dynamic instance and decomposes that instance’s stall into lifecycle phases—IQ/issue wait, memory service, execute, and ROB drain (writeback→commit). The dominant phase becomes the symptom class that Step 2 uses to choose its CGT entry point. The automated output is therefore a seed symptom: a (PC, dynamic instance, symptom-class) tuple that initiate dependency-graph-based structural localization, with optional filtering by function, bucket, or other user-specified targets. Step 2: Structural Localization Once Step 1 flags a severe instructionlevel stall and decomposes its lifecycle into dominant phases, the Causal Graph Traversal (CGT) module automatically localizes its microarchitectural root cause 2 . Operating directly over the typed MFIR edges, the CGT algorithm uses the targeted instruction and the relevant symptom event as a seed and traces backward strictly along the critical path of dependency resolution. CGT is symptomconditioned: it does not always begin at the Step 1 symptom instance. Instead, it selects a traversal root that matches the causal question implied by the dominant symptom, then traces backward strictly along the critical path over typed MFIR edges. As examples, for operand-readiness stalls, it starts at the symptom instruction and walks backward along dataflow dependencies to the producers that bound issue stage. For memory-service stalls, it starts at the stalling load and follows the memory path to the cache level and resource that delayed completion. For ROB-drain stalls, the symptom instance has finished execution but cannot retire; dataflow alone cannot explain the delay. CGT therefore identifies which older instruction occupied the ROB head during the victim’s writeback→commit window, pivots the walk to that dominant head, and traces backward from the prerequisite that prevented its retirement. The Step 1 instance remains the accounting anchor for total stall; the pivoted head is the structural root for localization. Operating directly over the typed MFIR subgraph reachable from the selected root, CGT evaluates competing dependents by their resolution times. When several dependencies could have bound progress, it keeps only the last-arriving (critical) predecessor at each hop, pruning earlier paths whose delays are absorbed by execution slack. Continuing this walk through inherent microarchitectural latencies and, where applicable, resource-contention pivots, CGT answers “where” and “when” execution was blocked: the precise temporal window, the instruction or packet node on the critical path, and the physical resource involved, separating induced structural contention from irreducible operational latency. Step 3: Cross-Layer Investigation This step pursues answering the “why” behind the bottleneck 3 . Transitioning to custom queries, the architect leverages the Analysis Engine (Section 2.4) to inspect the hardware resource state during the temporal window identified by the CGT (Section 3). Because the MFIR natively links physical hardware resource allocation events to their originating instructions and speculation states, the targeted analyses can leverage cross-layer SQL queries to investigate resource tenancy and relationships between instructions. This step is currently manually driven, where the user conducts drill down investigations through the MFIR to gain visibility into hidden anomalies, such as squashed wrong-path instructions or competing out-of-order instructions

Analysis Engine

Custom Queries

Automatic Analysis

1 Symptom Identification

"what"

Seed Symptom

2 Structural Localization (CGT)

"where/when"

3 Cross-Layer Investigation

"why"

Investigation Insights

4 Targeted Optimization

"how/the fix"

Figure 5: The Microflow End-to-End Workflow

Intermediate Representation (IR). Because the MFIR serves as a stable, unified contract, researchers can easily extend the framework by writing new modules that combine hardware state and software semantics without modifying the underlying tracing or compilation infrastructure.

3

Microflow End-to-End Workflow

We envision a four-stages workflow (Figure 5) within Microflow, though other potential uses are possible. This workflow guides a user from high-level coarse symptoms through steps of analysis and characterization leading finally to actionable insights that lead to optimizations. As depicted, in Figure 5, the Analysis Engine (Section 2.4) handles the first two steps automatically: Symptom Identification 1 and Structural Localization 2 . Its goal is to identify target instructions matching some user specified criteria (e.g., a threshold on front end stall cycles), and providing detailed microarchitectural analysis of these instructions. The workflow then transitions to custom analysis queries for Cross-Layer Investigation 3 , ultimately handing off investigation insights to the architect for the final targeted hardware/software optimization decisions 4 . These steps are partially automated in the current system, but the Microflow abstractions (the MFIR, and the SQL query interface) support further automation. We describe each of these stages next. Step 1: Symptom Identification The diagnostic process begins by answering “what” is wasting cycles 1 .Microflow does this in two automated layers over the compiled MFIR. First, a topdown workload classification applies an exact, cycle-accurate version of TMA [30], partitioning the trace into frontend, backend, badspeculation, and retiring buckets. This establishes the dominant performance class for the analyzed window without manual counter interpretation. Second, instruction-level symptom ranking operates on the MFIR Lifecycles table—the same per-dynamic-instruction records that power state-of-the-art PICS profilers [5, 11]. The framework aggregates stall time by PC, ranks the highest-cost committed instructions, and retains the top candidates for deeper analysis. Because lifecycles are tied back to originating symbols, the output is a ranked leaderboard of “where” cycles are spent. Crucially, Step 1 does not stop at a PC label such as “Reorder Buffer (ROB) drain” or 6

Microflow: Microarchitectural Causal Observability for Deep Cross-Layer Analysis and Optimization

Table 1: Microflow’s Overhead on mcf_r.

Conference’17, July 2017, Washington, DC, USA

Analysis Engine Symptom Identification

Stage

Time (s)

Comments

Simulation + Tracing E2E MFIR generation

81 331

Including warmup Parallel tracing + compilation

1. Symptom Identification 2. Structural Localization 3. Cross-Layer Investigation

0.42 2.62 0.43

MFIR-native TMA + Inst. lifecycles CGT MFIR Events Z Flows

Total analysis (Steps 1–3) Total E2E Workdlow

8.60 339.60

1

MFIR-native TMA

Rank PC Bucket

Share (%)

Back Speculation Frontend Bound Backend Bound Retiring

2

Symptom Leaderboard (top-5 committed PCs) 1 2 3 4 5

56.1 0.2 30.3 13.4

0x40531a 0x405313 0x40530f 0x405321 0x40531e

Dyn. Instances

IQ

D$

ROB

Total

Worst Instance

23,580 23,581 23,581 23,579 23,579

0.0M 0.0M 0.0M 7.2M 7.2M

5.1M 5.1M 5.1M 0.0M 0.0M

6.2M 5.9M 5.8M 2.7M 2.7M

11.3M 11.0M 10.9M 9.9M 9.9M

seq 5217022 (3781c) seq 5217019 (3760c) seq 5217018 (3760c) seq 2635799 (2277c) seq 2635798 (2276c)

Structural Localization

3

Causal Graph Traversal (CGT) 0x40531a (seq 5217022)

monopolizing critical structures. However, the interface enables automated analyses, which we plan to build as we continue to mature the tool. Step 4: Targeted Optimization Given the insights obtained from Step 3, the user can propose solutions to mitigate the observed behavior. Although this step is also manual in the current framework, we believe the ability to derive causal information, connected across different instructions and microarchitectural structures, with root cause analyses provide superior data to guide future automated optimizations and design space exploration.

A

Symptom IQ wait = 0, Memory Stall = 1952c, ROB Drain = 1829c

4

Causal Root Resolution ...

No

ROB State seq

In Out 5216772 c-18 c341 5216868 c10 c1916 5217020 c54 c2011 ... ... ... 5217022 c55 c2014

ROB Drain? Yes

Query the ROB state during the 1829 cycle window

Head Stall 158c (%9) 1563c (%85) 38c (%2) (≤19 cyc each) symptom

New CGT Root 0x40531e (seq 5216868)

B

5 X

A B C

E

4 Case Studies 4.1 A Workflow Example

Cycle

We walk through the four-stage workflow presented in Section 3 on the case study on 505.mcf_r (SPEC CPU 2017), a minimum-cost network-flow solver whose hot loop primal_bea_mpp combines pointer-chasing DRAM loads with data-dependent branches. Table 1 reports the wall-clock cost of each automated workflow stage on this MFIR. Figure 6 illustrates this workflow on MFIR. Symptom Identification Microflow’s automatic TMA module classifies the execution window as bad-speculation dominated, with backend stalls as the second-largest bucket 1 . Next, a second analysis module builds a per dynamic instruction instance stall attribution to find PICS-based aggregate stalls per commited PCs (IQ wait + D-cache miss + ROB-drain). A seed ranker then sorts committed PCs by these aggregate stall and stores the top-n candidate symptoms 2 . The workflow then selects rank 1 from this list without manual instance picking as the initial seed for CGT pass 3 . This selected instruction instance exhibits a striking anomaly: it spends 0 cycles waiting in the Issue Queue but suffers a massive 1829 cycles waiting to commit after completing writeback. This specific symptom class (ROB drain) definitively dictates the traversal strategy for the next step. Structural Localization Because the selected seed instruction suffers from commit stage backpressure (finishing execution but failing to retire), directly traversing its data-flow or resource dependencies would be ineffective. Instead, the CGT module must first perform Causal Root Resolution to pivot from the naive symptom to the true hardware bottleneck 4 . By automatically querying the ROB state during the exact 1829 cycle temporal window where the symptom instruction was stalled (writeback to commit), the algorithm identifies the specific older instruction that occupied and blocked the ROB head. This dominant head instruction becomes the calibrated traversal root. The dominant head—an add load five

J

I

H

G

F

12

115

116

117

150

D 1731c 1829c 185

1916

2014

Figure 6: End-to-end workflow case study (mcf_r)

loop iterations earlier—holds the ROB for 1563 (%85) of the 1829 drain cycles. From this true structural root, the CGT traces backward strictly along the critical path of dependency resolution over the typed MFIR edges 5 . The algorithm answers the causal question: “Which ROB head instruction blocked commit, and why could that head not retire?” The traversal exposes a cross-loop iteration chain: the head instruction is a load whose address depends on an earlier mov within the same iteration, which subsequently misses to the off-chip DRAM for 1766 cycles. The graph perfectly demonstrates that this 1731 cycle memory service delay overlaps and absorbs the ROB head interval. It is the fundamental reason the head cannot commit, rather than an additional sequential penalty stacked on top of the 1829 cycle drain. Crucially, Microflow’s modular architecture allows architects to seamlessly extend this causal resolution by enabling deeper, multidomain event tracing. By activating the DRAM event domain, the framework captures high-fidelity memory controller and DRAM interactions. This deeper traversal resolves the structural overhead with unprecedented clarity: the 1669 cycle L2 load miss decomposes into 1465 cycles of memory controller queue wait, 122 cycles of DRAM service following a row open event, and 81 cycles of return transit to the L3 cache. This analysis definitively proves that the binding latency is primarily driven by structural controller queuing, not the raw DRAM access time. 7

Conference’17, July 2017, Washington, DC, USA

...

0x40531a : mov 0x18(%rax), %rcx loop iter. 43196

-

-

issue

wb

...

add (%rcx), %r8 loop iter. 43191 - seq 5216868

Software

issue J

seq 5216867

0x40531e :

commit

ROB Drain 1829c

X

seq 5217022

0x40531a : mov 0x18(%rax), %rcx loop iter. 43191

Saber Ganjisaffar, Chengyu Song, and Nael Abu-Ghazaleh

load µop ...

ALU µop

Microarchitecture

writeback I

Memory/Resource Resolution

ROB_HEAD

L

lsq.load_exec

REG_DEP H

issue

retry

G

lsq.send_req F

lsq.fill_recv C MERGE

L1D port blocked for 33c SPAWN

paddr 0x2ce4a8 packet flow

l1d.miss l1d.mshr.alloc l1d.send_req

l1d.recv_resp

commit

D

DRAM round

Resources

... wb B issue wb

l1d.fill l1d.mshr.serv_targets l1d.mshr.dealloc

E

Intra-Flow Dependencies Data/Reg Flow Dependencies

A

commit

ACQUIRE

trip 1760c RELEASE

l1d.mshr.entry #4

Structural serialization (ROB)

ACQUIRE

...

l1d.line #26

Figure 7: The MFIR demonstration of the mcf benchmark symptom and its root causes. Cross-Layer Investigation Structural localization binds the ROBdrain instance to two mechanisms on the critical path as it is illustrated in Figure 6 and 7. First, the dominant ROB-head load at 0x40531e (seq 5216868) cannot retire because its off-chip memory request remains outstanding for 1766 cycles of which 1465 cycles is wasted on memory controller queue wait. Second, the same load briefly replays on a closed L1D port for 33 cycles. CGT therefore explains the drain as “long memory controller queue wait plus brief cache-port blocking.’ Step 3 uses MFIR’s cross-layer queries to answer those follow-on questions. By linking pc, seq_num, and packet lifecycles, MFIR reveals that the pointer-chase loop systematically stacks DRAM transactions across iterations: when the binding head load enters the controller at cycle 216, 75 older-strand L3 misses from prior loop iterations are still in flight; on average, 99 hot-loop L3 misses overlap in this region. Older correct-path strand traffic dominates run-wide controller occupancy (21.6 M service cycles vs. 15.0 M for wrong-path), so the ROB-head miss arrives into a queue already backed up by previous iterations of the same software loop body. The brief L1D port-block episode on the binding path raises a follow-on question that CGT alone cannot answer: instructionflow edges connect events along a single dynamic instance, but they do not explain why an asynchronous cache resource closed the port during the replay window. We therefore issue a cross-layer join over cache events for the duration of the retry and find that the port is blocked because the L1D-MSHR pool is full. That occupancy cue motivates a second probe: MFIR joins MSHR tenansies (l1d.mshr.alloc to l1d.mshr.dealloc windows) to instruction flows and software pc/seq_num, revealing which tenants hold the finite pool during the retry window. The L1D-MSHR pool is a crosslayer interaction point between TMA’s Bad Speculation and Backend Bound buckets: wrong-path iterations inside primal_bea_mpp allocate entries that outlive squash, while many correct-path iterations simultaneously hold slots for in-flight L3 misses. When the ROBhead load at 0x40531e issues, it competes with tens of prior loop iterations for one of 12 entries. That is structurally a cross-iteration (cross-loop-trip) resource contention, distinct from but compounding the longer DRAM-queue stacking that dominates the 1669 cycle off-chip miss. Ultimately, this demonstrates how finite on-chip resources couple backend memory pressure to brief port closure and to loop-level contention, a complex microarchitectural behavior that instruction-only dependence graphs simply cannot express.

Fetch/Dispatch Timeline (One Misprediction is ~25 Cycles) Refill (~15 Cycles)

Productive (~8 Cycles)

CP+WP Mixed

Squash A

Refill (~15 Cycles)

Productive ...

Squash B

IQ Occupancy Snapshots (64-Entry IQ) T0 = 0 Squash A

CP (old) 16

T1 = 5 Refilling

CP (old) 12

T2 = 15 Productive T3 = 18 Branch B Misspredicts

CP (new) 10

CP 6

3

T5 = 22 IQ Full

2

empty (42 slots)

CP (new) 28

CP 4

T4 = 20 WP Flooding

T6 = 25 Squash B

Freed by Squash (48 slots)

CP (before B) 24

CP (before B) 20

CP (before B) 16

CP (old) 14

empty (30 slots)

WP 8

empty (28 slots)

WP (growing) 26

empty (15 slots)

WP (flooding) 46

Full!

Freed by Squash (50 slots)

Figure 8: WP instructions reducing IQ capacity in leela_r.

4.2

Uncovering Hidden Misprediction Costs

4.2.1 Symptoms and Aggregate Diagnosis. Table 2 summarizes simulator statistics and the 3-level TMA breakdown computed automatically by Microflow directly on the MFIR. Both agree on the surface diagnosis: leela_r is dominated by branch misprediction, with Bad Speculation consuming 47.7% of pipeline slots and BackendCore a further 14.8%. An architect reading this hierarchy would conclude: fix conditional branch prediction and treat IQ structural pressure and operand latency as independent backend issues. This conclusion is misleading. TMA’s taxonomy is additive by construction: each instruction occupies exactly one bucket, and categories are assumed independent. The 14.8% Backend-Core slot sits adjacent to Bad Speculation in the hierarchy but shares no causal edge with it. Neither TMA nor simulator statistics can determine whether these stalls are caused by the preceding mispredictions or are genuinely independent. Answering this questions requires per-instruction causal tracing, which Microflow provides. 4.2.2 Hidden Amplification Mechanisms. The MFIR’s perinstruction lifecycle records and cross-flow causal edges show three amplification mechanisms through which misprediction damage propagates far beyond the pipeline slots that TMA attributes to Bad Speculation. These mechanisms are undetectable from aggregate metrics. 8

Microflow: Microarchitectural Causal Observability for Deep Cross-Layer Analysis and Optimization

Table 2: Analysis of leela_r: Simulator metrics, 3-Level TMA report calculated from MFIR, and Microflow-unique causal insights unreachable by aggregate methods.

main() → play_random()

L1: Retiring / Frontend / Backend-Mem L1: Bad Speculation L2: Conditional / Indirect-Cond L2: Return (RAS) / BTB miss L1: Backend-Core L2: IQ Wait / ROB Drain / Execute L3: IQ structural (IQ ≥ 75% full) L3: IQ dependency (operand wait) L3: ROB cascade (older inst blocks)

Branch B Mispred.

Value

0

0

n=789

5

n=288,725

10

n=102,154

15

1-2

3-5

6+

WP RAS pushes / epoch

CP avg IQ wait (cycles)

20

n=39,976

Med. gap to next mispred (cyc)

25

300 200 100 0 100

More WP Call Exec.

Squash + RAS Restore

get_board

get_board

self_atari

self_atari

get_board self_atari

play_random

play_random

play_random

...

...

...

...

w_path1 (WP)

RAS

main

get_pat (WP)

get_pat (WP)

get_pat (WP)

get_pat (WP)

New squash happens faster due to ret mispred.

Time

t1

t2

t3

t4

t5

t6

w_path2 (WP)

RAS Corruption Cascade. Simulator statistics show 99.96% of Return Address Stack (RAS) predictions are incorrect, with 3.10M RAS squash-restores against 3.37M pushes, meaning 92% of all pushes required restoration due to WP speculation. Microflow correlates per-squash-epoch WP RAS push counts with the cycle gap to the next misprediction as shown in Figure 9 (a). Squash epochs in which WP execution speculatively executes 3–5 call instructions lead to the next misprediction 3.7× sooner on average than epochs with zero WP calls. The mechanism is a self-reinforcing cascade: each misprediction triggers speculative WP calls that pollute the RAS, causing the subsequent ret to mispredict; that misprediction generates more WP calls, sustaining the cascade (Figure 10).

r = 0.964

50

Return Mispred.

operands may be ready, they may want to wake up dependent instructions, but there’s no IQ space because 46 WP instructions have flooded the queue. With a median inter-squash gap of only 26 cycles and a pipeline refill latency of 8.2 cycles, the IQ is chronically inflated by WP instructions that have not yet been squashed. The pipeline never reaches steady state, it’s always either draining WP from the last squash, or filling with WP from the next misprediction. The ∼287𝐾 Rename IQ Full events in simulator statistics confirm that rename stalled because the IQ was full of WP instructions.

400

0

Squash + RAS Restore

Figure 10: Self-reinforcing cascade of return mispredictions in leela_r, triggered by WP call execution corrupting the RAS.

93.5% 61.5% of instructions 29% 34.7 vs 21.5 (+61%) 𝑟 = 0.964 3.7 × faster 64 × 48.1% (59.8% cross-func.) 74.2% 77%

500

WP Call Exec. (Corrupt RAS)

Cascade Mispred.

TOS

(b) IQ Capacity Theft

3.7× faster in average

30

← mispredicts here

no_eye (WP)

Microflow’s Unique Causal Insights

(a) RAS Cascade

← call pushes ret→self_atari

Branch B

nbr_crit (WP)

37.4% / 0.1% / 0.0% 47.7% 66.9% / 32.5% 0.1% / 0.6% 14.8% 46.6% / 36.9% / 5.6% 17.1% 20.0% 11.7%

Backend-Core stalls within 50 cycles of squash True misprediction cost (reattributed) TMA underestimate of mispred cost WP vs CP IQ occupancy at insert WP IQ occupancy → CP dispatch delay RAS cascade: re-mispred acceleration Backend amplification (retire/execute) Mispredictions in cross-func. bursts Top 8 PCs share of WP damage Pipeline productive fraction

← call pushes ret→play_random_move

→ get_board()

0.653 / 47.7% 10.0M / 9.1M 422,591 286,983 108 / 271,005 3.37M / 3.10M 61.1% of all cycles

Microflow Automatic 3-Level TMA on MFIR

← call pushes ret→main

→ self_atari()

Aggregated Simulator Metrics IPC / Squash rate Committed / Squashed insts Branch mispredicts Rename IQ-full stalls RAS correct / incorrect RAS pushes / squash-restores Zero-commit cycles

Conference’17, July 2017, Washington, DC, USA

150

WP IQ occupancy (entries)

Figure 9: MicroFlow-revealed amplification mechanisms. (a) Median inter-misprediction gap by WP RAS push count. (b) Per-time-bin correlation between WP IQ occupancy and CP dispatch delay.

Cross-Function Misprediction Bursts. Aggregate statistics report misprediction as a uniform tax. The Microflow reveals that mispredictions cluster into rapid bursts, separated by calmer periods. Defining a burst as a sequence of consecutive mispredictions with < 20-cycle gaps, 48.1% of all mispredictions occur in bursts (Figure. 11 (a)). Of those, 59.8% are cross-function: different MCTS boardevaluation routines each hitting their own data-dependent branch in rapid succession. The root cause is structural: the MCTS playout path traverses a dense chain of data-dependent branches across self_atari, nbr_criticality, get_extra_dir, and related routines (Figure. 11 (b)), each evaluated on board state that changes every iteration. The probability of traversing the sequence without a single misprediction is vanishingly small. The bursts create a feedback loop: each misprediction pollutes the global branch history register with WP branch outcomes and corrupts the RAS with WP calls, degrading prediction accuracy for subsequent branches and

Instruction-Queue Capacity Theft. Wrong-path (WP) instructions occupy Instruction Queue (IQ) entries that correct-path (CP) instructions need for dispatch. The Microflow differentiates IQ occupancy at the moment of insertion by path correctness: WP insertions see an average IQ occupancy of 34.7 entries versus 21.5 entries for CP insertions, a 61% inflation. The per-time-bin temporal correlation between WP IQ occupancy and CP dispatch delay is 𝑟 = 0.964 as shown in Figure 9 (b), establishing a clear causal link. Critically, the theft damage is a temporal: it occurs before the squash signal arrives as it is demonstrated in Figure 8. At T5 , there are 16 CP instructions (older than branch B) that are trapped in the IQ. Their 9

Conference’17, July 2017, Washington, DC, USA

(a) Burst Distribution

219310

Total mispredictions

(b) Misprediction Density

61468

(5 br)

FB::update_board_fast

(53 br)

R::randint

(1 br)

5330

50K 1

2

(20 br)

FS::play_random_move

100K

0

(1 br)

FB::get_extra_dir FB::nbr_criticality

150K

6265 2840

1407

3

5

4

Burst length

(1 br)

R::get_Rng (3 br)

FB::no_eye_fill

0

6+

MicroFlow-guided path. Microflow decomposes the same misprediction damage into three causally distinct mechanisms, each with a mechanistically grounded IPC projection. Each relies on per-instruction WP/CP labels, speculative lifecycle records, and cross-flow causal edges that TMA, hardware PMUs, and simulator statistics cannot provide. IQ Capacity Theft Cost: Because the MFIR labels every IQ entry as wrong-path or CP, it directly quantifies how much IQ capacity is wasted on instructions that will be squashed. A regression over execution windows shows a strong negative correlation (𝑟 =−0.919) between WP IQ occupancy and IPC: each additional WP entry measurably slows the CP. Projecting a 15%–40% reduction in WP instructions, the range targeted by the hardware mechanisms in 4.2.4, yields +13%–+22% IPC. RAS Corruption Cascade Cost: Squash epochs with zero WP calls establish a cascade-free inter-squash rate of 77.1 cycles. Comparing this baseline against the observed epoch count yields 232,795 cascade-induced extra squashes; at a net saving of 16.5 − 8.2 = 8.3 cycles each, eliminating them frees 232,795 × 8.3 = 1.94M cycles, projecting +15% IPC. WP Burst Concentration: Hardware misprediction counters rank PCs by mispredict frequency; the Microflow ranks by the wrongpath work each PC spawned, a fundamentally different signal. The top-8 PCs by WP damage account for 74.2% of attributable WP instructions, equal to 36.4% of total WP IQ pressure. Applying this reduction, within the calibrated 15–40% regression range already evaluated in IQ regression, requiring no extrapolation, projects +21% IPC, with a partial two-PC software fix measured at +2.40% IPC on gem5, validating the model.

(46 br)

FB::self_atari

48.1% in bursts

200K

Saber Ganjisaffar, Chengyu Song, and Nael Abu-Ghazaleh

50

100

150

200

Mispred / 1K insts

250

Figure 11: (a) Misprediction burst classification: 48.1% of mispredictions cluster into bursts (< 20-cycle gaps). (b) Per-function misprediction density for the top burstparticipating functions.

100

Retiring FE Bound BE-Mem

BE-Core Bad Spec. Reattr. (13.8%)

(b) MicroFlow Counterfactual Speedup unachievable (data-dep. branches)

0.90 0.85

60

0.80

+31%

IQ theft fix

+13%

0.75

40

0.70

20 0

TMA upper bound µArch: WP throttling (IQ theft) µArch: RAS checkpointing (Cascade) SW: 2/8 PCs fixed (measured +2.4%) SW: 8/8 PCs fixed (projected +21%)

0.95

80

IPC

Instruction allocation (%)

(a) Reattribution

0.65 TMA MicroFlow

e elin

Bas

et: arg d. A t pre TMrfect pe

IQ

Rel

ief

+17%

RAS +22% cascade fix +15% 71% theor.

+21% 66%

SW Fix theor.

+2.4%

s s S RA int chlesCs chlesCs 15% ef 25% ef 40% i i po an 8 P Bran 8/8 P Rel Q Rel eck Br 2/ IQ I Ch

Figure 12: (a) MicroFlow reattribution raises true misprediction cost to 61.5% (29% TMA underestimate). (b) Three MicroFlow-guided counterfactuals vs. TMA’s unachievable upper bound. sustaining the burst. Paradoxically, per-misprediction WP instruction counts are 42% lower in bursts than in isolation (132 vs. 228 WP instructions), because each burst misprediction truncates the previous one’s speculative window, a speculative-window truncation effect that makes bursts appear less damaging by aggregate WP metrics while causing the most severe throughput loss.

4.2.4

Actionable Insights.

(1) Fix 1: WP fetch throttling. A microarchitectural controller that monitors IQ occupancy and recent squash rate can throttle speculative fetch when both are elevated, limiting WP IQ inflation without stalling the correct-path front-end. TMA registers IQ-structural stalls but cannot identify their cause; only the MFIR’s WP/CP path labels establish that WP instructions are responsible and quantify the per-entry throughput cost. (2) Fix 2: RAS checkpointing. Checkpointing the RAS at speculative call boundaries prevents garbage return addresses from corrupting predictor state before the squash signal arrives. The ∼271𝐾 RAS mispredictions in simulator statistics appear as a 0.1% Return-type Bad Speculation entry; no existing tool connects them to their role as a misprediction-frequency multiplier, which only Microflow’s per-epoch correlation reveals. (3) Fix 3: Branchless board evaluation. The Microflow’s perPC WP depth attribution ranks eight PCs as responsible for 74.2% of attributable WP damage. Crucially, four of these are already branchless routines whose ret instructions mispredict solely because preceding WP calls corrupted the RAS. Hardware counters would flag them as high-mispredict PCs with no software fix available, while Microflow correctly redirects attention to Fix 2. Disassembling all eight PCs reveals that the 36.4% WP pool decomposes into three structurally distinct categories, each requiring a different intervention (Table 3). The 21.4% from RAS cascade victims has ret as the mispredicting instruction: software cannot fix a ret mispredict caused by a garbage

4.2.3 Quantifying the True Cost. Microflow measures the temporal distance between every Backend-Core-bound instruction and the nearest preceding squash event. If Backend-Core stalls were independent of misprediction, this distance should match the baseline expected gap of 35.5 cycles given the observed squash rate. Instead, Backend-Core instructions average only 7.9 cycles from the preceding squash, 4.5× closer than the baseline, with 93.5% occurring within 50 cycles versus 75.5% expected under independence. Reattributing this squash-proximate fraction raises the true misprediction cost from 47.7% to 61.5%, a 29% TMA underestimate (Figure 12 (a)). TMA-guided path. TMA flags Bad Speculation at 47.7% and implies better branch prediction as the fix. The theoretical upper bound of perfect prediction, eliminating all squash overhead, yields +31% IPC, but is structurally unachievable: the dominant mispredicting functions evaluate data-dependent Go board state that changes on every MCTS playout, so no predictor can learn their outcomes regardless of table size or history length. TMA identifies the symptom correctly but the implied remedy is inapplicable. 10

Microflow: Microarchitectural Causal Observability for Deep Cross-Layer Analysis and Optimization

Conference’17, July 2017, Washington, DC, USA

RAS entry, only Fix 2 can. The 6.3% from algorithmic early-exit loops cannot be converted to branchless form without changing program semantics, making Fix 1’s WP throttling the appropriate lever. The 8.7% from two functions (nbr_criticality, fast_ss_suicide) contains genuine conditional branches with trivial branchless equivalents; converting them with five lines of code yields a measured +2.40% IPC, confirming the regression model produces verifiable predictions. The full +21% IPC projection requires all three rows; the gap from the partial fix reflects that Fix 1 and Fix 2 must supply the remaining 27.7%. Table 3: Top-8 PC WP damage by root cause and fix. Category

PCs

% WP

Branchless-convertible Measured RAS cascade victims Algorithmic early-exit

2

8.7%

4 2

21.4% 6.3%

Software +2.40% IPC (gem5) Hardware (Fix 1) Microarch (Fix 2)

Total top-8

8

36.4%

+21% IPC proj.

Figure 13: Normalized wall-clock at 100 M instructions.

Fix

5.1

Figure 13 decomposes the end-to-end wall-clock cost at 100 M instructions into its two contributing steps: traced simulation and MFIR compilation. On gem5, sequential compilation is the dominant cost, averaging 14.3× the baseline wall time on its own—a direct consequence of the rich per-instruction event data gem5 generates. Running compilation in parallel to the simulation eliminates most of this overhead (using trace partitioning): partitions are compiled as simulation produces them, leaving only the fraction that spills beyond the simulation window (2.0× on average). The resulting parallel end-to-end cost is 7.8× baseline (avg), with all benchmarks except imagick below 10×. On ChampSim, compilation is lightweight (0.18× baseline) and always finishes within the simulation window, so the parallel end-to-end cost collapses to the traced-simulation overhead of 2.4×—identical to the slowdown from tracing alone. Figure 14 reports three scalability metrics across 1,M–100,M instruction regions. Panel (a) shows that MicroFlow captures 10–20 events per instruction on gem5, varying only ±3% across the full range—tracing overhead is therefore strictly proportional to instruction count and does not compound with region size. Panel (b) shows simulation slowdown relative to the untraced baseline: gem5 converges to 5.9× at ≥10,M instructions and stays flat, while ChampSim incurs only 2.4× due to its lighter internal state. Panel (c) shows MFIR storage normalized per million instructions: all benchmark lines are flat across scales, confirming linear storage growth at 225– 510,MB/Minst depending on workload complexity.

A TMA-guided optimization would recommend better branch prediction, such as larger TAGE tables, longer history, indirect predictors, an approach that cannot succeed for fundamentally datadependent MCTS branches and that addresses none of the three mechanisms above. Microflow uniquely decomposes the 36.4% WP damage pool and attributes each slice to the correct intervention.

5

Evaluation

Component

gem5

ChampSim

CPU Pipeline width IQ / ROB LSQ Physical regs Branch predictor BTB / FTQ L1-I L1-D L2 LLC Memory

x86-64 O3, 3.5 GHz 12-wide 194 IQ; 512 ROB 144 loads; 112 stores 448 int; 400 vec/fp TAGE-SC-L, 64 KiB 16 K BTB; 24 FTQ 32 KiB, 8-way, 4 cyc; 8 MSHRs 64 KiB, 16-way, 5 cyc; 12 MSHRs 1 MiB, 16-way, 14 cyc; 32 MSHRs 2 MiB, 16-way, 44 cyc; 48 MSHRs DDR4-2400, 1 ch., 4 GiB

Trace-driven O3, 4.0 GHz 12-wide 194 sched.; 512 ROB 144 LQ; 112 SQ 448 (unified) bimodal, 16 K 8 K BTB; — Same Same Same Same DDR4-3200, 1 ch.

Overhead, Scalability, and Portability

Table 4: Arch. Configuration in gem5 and ChampSim.

All experiments use two cycle-level simulators configured to approximate the Intel Golden Cove (Alder Lake) microarchitecture; Table 4 lists the full configuration for each. We use the cycle-accurate gem5 simulator [18] and its O3 CPU model in System Emulation (SE) mode. Representative phases are identified with SimPoint [13]; each benchmark is fast-forwarded to its representative phase checkpoint, warmed up with 10M Atomic instructions, then simulated in detailed O3 for 10M committed instructions on leela and 2M on mcf for the case studies (as well as the workflow example in section 4.1). To evaluate the generalizability to other simulators as well, we additionally use the trace-driven Championship Simulator [9] with the matched Table 4 settings, driven by SimPoint traces from the 3rd Data Prefetching Championship (DPC-3) [9]; each run warms up for 10M retired instructions.

Figure 14: MicroFlow overhead across 1M–100M regions (eight SPEC 2017 benchmarks; thin lines = per-benchmark, thick = avg). (a) Events per instruction (gem5). (b) Simulation slowdown vs. baseline; solid = gem5, dashed = ChampSim. (c) MFIR storage per million instructions. 11

Conference’17, July 2017, Washington, DC, USA

Saber Ganjisaffar, Chengyu Song, and Nael Abu-Ghazaleh

Table 5: Automated Step 1, Symptom Identification, and Step 2, Structural Localization on SPEC 2017 benchmarks.

5.2

Bench.

TMA top

gcc mcf cactuBSSN namd lbm xalancbmk deepsjeng leela

Bad Speculation Bad Speculation Backend Bound Backend Bound Retiring Backend Bound Backend Bound Bad Speculation

Inst. stall

Symptom

516 IQ wait 3,876 ROB drain 774 Memory service 841 IQ wait 3,978 ROB drain 2,334 IQ wait 1,553 ROB drain 1,139 IQ wait

CGT binding DRAM miss @ 0x505390 (486 cyc); operand chain @ 0... ROB head 0x405317 · ld: compute latency @ 0x40530f ... memory-bound load 0x4f31be · ld operand chain @ 0x5b68b3 (867 cyc) ROB head 0x402f3d · ld: operand chain @ 0x402f3d · ld... operand chain @ 0x69b038 (242 cyc) ROB head 0x41299a · ld: operand chain @ 0x41299a · ld... operand chain @ 0x433d0d (227 cyc)

Step 2 (s)

1.55 1.71 0.72 1.10 0.84 1.36 1.16 1.62

7.57 6.68 2.57 6.53 8.84 8.07 8.17 8.32

these prior graphs are single-layer and built over the committed path: the memory hierarchy is an abstracted weighted edge or a structural-hazard model, prefetch traffic is absent, squashed instructions are not vertices, and there is no software semantic layer to map event to their originating software constructs. MFIR records deeper microarchitectural entities and behaviors such as end-to-end memory transactions and prefetch requests as first-class flows and preserves each resource holder’s information such as speculative status, it extends these established critical-path and interaction-cost analyses to the cross-layer and wrong-path resource attribution that a single-layer graph fundamentally cannot express.

Automated Diagnosis Across Workloads

Table 5 summarize Steps 1–2 on a set of SPEC CPU 2017 benchmarks. Step 1 ranks stall PCs by aggregate lifecycle cost; Step 2 autoselects the worst dynamic instance at the rank-1 PC, classifies its dominant symptom (IQ wait, ROB drain, or memory service), and reports the binding mechanism recovered by symptom-conditioned CGT. Symptom classes are heterogeneous: IQ-wait cases localize to DRAM misses or multi-instruction operand chains; ROB-drain cases pivot to the commit-head instruction and name its upstream binding root.

6

Step 1 (s)

Related Work 7

Per-instruction and top-down attribution. Top-Down Microarchitecture Analysis (TMA) [30] sorts pipeline issue slots into a Retiring/Bad-Speculation/Frontend/Backend hierarchy from a small set of counters, while TEA [11] and DIP [5] build time-proportional Per-Instruction Cycle Stacks (PICS) from a fixed signature of microarchitectural events, anchored at commit and at dispatch, respectively. All three are post-silicon, hardware-counter profilers: TMA reads production performance-monitoring units, and TEA and DIP add lightweight signature hardware to the core. They are therefore bounded by what counters can expose, rely on statistical sampling to keep overhead low, and report where cycles are lost—at slot or instruction granularity over a fixed event vocabulary– rather than the typed dependences that explain why. MFIR is instead a pre-silicon, simulator side substrate that subsumes them. During trace compilation it materializes a per-dynamic-instruction Lifecycle table that decomposes each instruction’s latency across pipeline stages (fetch, decode, rename, dispatch, issue-wait, execute, memory, writeback, commit). A TMA bucketization, a commit-anchored PICS, or a dispatch-anchored PICS is then a projection of this table; because the table is exact and per-instance rather than sampled, it is the un-approximated reference these hardware profilers estimate. Dependence-graph critical-path and interaction analysis. A second line models execution as a dependence graph and reasons about criticality. Fields et al. [7] introduced the microexecution graph and interaction cost which formalizes when two optimizations are super- or sub-additive; Calipers [10] casts this as a modeling and what-if framework over a trace and a microarchitecture model, and ArchExplorer [3] builds a time-aligned graph from simulation to drive design-space exploration via resource reassignment. MFIR’s typed inter-flow edges are themselves a microexecution dependence graph, so building such a graph and computing interaction cost, a structural what-if, or a resource-reassignment is a query over MFIR together with its counterfactual replay. Crucially,

Concluding Remarks

Understanding why an architecture underperforms is the central challenge of pre-silicon performance analysis. Microflow addresses this goal by making causal structure a first-class object of simulation: Microtracer annotates events with flow and resource identifiers, the trace compiler assembles them into the MFIR causal graph, and the Analysis Query Engine exposes it as typed, declarative relations supporting reusable analysis modules. In two case studies, Microflow uncovered hidden causal mechanisms invisible to aggregate profiling and TMA, motivating targeted interventions that delivered substantial IPC gains beyond what existing tools could identify or justify. Looking ahead, MicroFlow’s architecture opens several promising directions. At the analysis layer, ML agents can translate naturallanguage prompts into MFIR SQL queries, dramatically lowering the expertise barrier, while more advanced agents could orchestrate closed-loop exploration—interpreting MicroFlow output, proposing microarchitectural modifications, triggering new simulation runs, and iterating. Retrieval-augmented approaches such as CacheMind [21] would also benefit directly from MFIR as a structured retrieval substrate, replacing pattern matching over raw logs with semantically typed causal queries. Beyond CPUs, the simulatorindependence design—a generic event tracing API decoupled from the simulation backend—enables integration with GPU simulators, memory-system simulators, and ML accelerators with minimal adaptation; the primary challenge is the software semantic reconstruction layer, which currently targets CPU ISAs and would require new extractors for CUDA PTX, OpenCL kernels, or MLIR graphs. Finally, we envision MicroFlow as the foundation of a communitydriven ecosystem where standardized trace formats and a shared MFIR schema foster reproducibility and artifact sharing, enabling researchers to exchange workloads, analysis plugins, and optimization insights across the architecture community. 12

Microflow: Microarchitectural Causal Observability for Deep Cross-Layer Analysis and Optimization

References

Conference’17, July 2017, Washington, DC, USA

[23] Avadh Patel, Furat Afram, and Kanad Ghose. 2011. Marss-x86: A qemu-based micro-architectural and systems simulator for x86 multicore processors. In 1st International Qemu Users’ Forum. Citeseer, 29–30. [24] Ritik Raj, Sarbartha Banerjee, Nikhil Chandra, Zishen Wan, Jianming Tong, Ananda Samajdhar, and Tushar Krishna. 2025. SCALE-Sim v3: A modular cycleaccurate systolic accelerator simulator for end-to-end system analysis. In 2025 IEEE International Symposium on Performance Analysis of Systems and Software (ISPASS). IEEE, 186–200. [25] Daniel Sanchez and Christos Kozyrakis. 2013. ZSim: Fast and accurate microarchitectural simulation of thousand-core systems. ACM SIGARCH Computer architecture news 41, 3 (2013), 475–486. [26] Sameer S Shende and Allen D Malony. 2006. The TAU parallel performance system. The International Journal of High Performance Computing Applications 20, 2 (2006), 287–311. [27] Rafael Ubal, Julio Sahuquillo, Salvador Petit, and Pedro Lopez. 2007. Multi2sim: A simulation framework to evaluate multicore-multithreaded processors. In 19th International Symposium on Computer Architecture and High Performance Computing (SBAC-PAD’07). IEEE, 62–68. [28] Vincent M Weaver. 2013. Linux perf_event features and overhead. In The 2nd international workshop on performance analysis of workload optimized systems, FastPath, Vol. 13. 5. [29] Thomas F Wenisch, Roland E Wunderlich, Michael Ferdman, Anastassia Ailamaki, Babak Falsafi, and James C Hoe. 2006. SimFlex: statistical sampling of computer system simulation. IEEE Micro 26, 4 (2006), 18–31. [30] Ahmad Yasin. 2014. A top-down method for performance analysis and counters architecture. In 2014 IEEE International Symposium on Performance Analysis of Systems and Software (ISPASS). IEEE, 35–44.

[1] Laksono Adhianto, Sinchan Banerjee, Mike Fagan, Mark Krentel, Gabriel Marin, John Mellor-Crummey, and Nathan R Tallent. 2010. HPCToolkit: Tools for performance analysis of optimized parallel programs. Concurrency and Computation: Practice and Experience 22, 6 (2010), 685–701. [2] Advanced Micro Devices, Inc. 2025. AMD uProf. https://www.amd.com/en/ developer/uprof.html. Accessed: October 2025. [3] Chen Bai et al. 2023. ArchExplorer: Microarchitecture Exploration via Bottleneck Analysis. In 56th Annual IEEE/ACM International Symposium on Microarchitecture (MICRO). [4] David Boehme, Todd Gamblin, David Beckingsale, Peer-Timo Bremer, Alfredo Gimenez, Matthew LeGendre, Olga Pearce, and Martin Schulz. 2016. Caliper: performance introspection for HPC software stacks. In SC’16: Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis. IEEE, 550–560. [5] Silvio Heverton Campelo de Santana, Joseph Rogers, Lieven Eeckhout, and Magnus Jahre. 2026. Chips Need DIP: Time-Proportional Per-Instruction Cycle Stacks at Dispatch. In 31st ACM International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS), Volume 2. 361–376. [6] Trevor E Carlson, Wim Heirman, and Lieven Eeckhout. 2011. Sniper: Exploring the level of abstraction for scalable and accurate parallel multi-core simulation. In Proceedings of 2011 International Conference for High Performance Computing, Networking, Storage and Analysis. 1–12. [7] Brian A. Fields, Rastislav Bodík, Mark D. Hill, and Chris J. Newburn. 2003. Using Interaction Costs for Microarchitectural Bottleneck Analysis. In 36th Annual IEEE/ACM International Symposium on Microarchitecture (MICRO-36). IEEE, 228– 239. [8] Markus Geimer, Felix Wolf, Brian JN Wylie, Erika Ábrahám, Daniel Becker, and Bernd Mohr. 2010. The Scalasca performance toolset architecture. Concurrency and computation: Practice and experience 22, 6 (2010), 702–719. [9] Nathan Gober, Gino Chacon, Lei Wang, Paul V Gratz, Daniel A Jimenez, Elvira Teran, Seth Pugsley, and Jinchun Kim. 2022. The championship simulator: Architectural simulation for education and competition. arXiv preprint arXiv:2210.14324 (2022). [10] Hossein Golestani et al. 2022. Calipers: A Criticality-aware Framework for Modeling Processor Performance. In 36th ACM International Conference on Supercomputing (ICS). [11] Björn Gottschall, Lieven Eeckhout, and Magnus Jahre. 2023. TEA: TimeProportional Event Analysis. In 50th Annual International Symposium on Computer Architecture (ISCA). [12] Dragana Grbic and John Mellor-Crummey. 2025. Analyzing the Performance of Applications at Exascale. In Proceedings of the 39th ACM International Conference on Supercomputing. 792–806. [13] Greg Hamerly, Erez Perelman, Jeremy Lau, and Brad Calder. 2005. Simpoint 3.0: Faster and more flexible program phase analysis. Journal of Instruction Level Parallelism 7, 4 (2005), 1–28. [14] Intel Corporation. 2025. Intel® VTune™ Profiler. https://www.intel.com/content/ www/us/en/developer/tools/oneapi/vtune-profiler.html. Accessed October 2025. [15] Mahmoud Khairy, Zhesheng Shen, Tor M Aamodt, and Timothy G Rogers. 2020. Accel-sim: An extensible simulation framework for validated gpu modeling. In 2020 ACM/IEEE 47th Annual International Symposium on Computer Architecture (ISCA). IEEE, 473–486. [16] Andreas Knüpfer, Holger Brunst, Jens Doleschal, Matthias Jurenz, Matthias Lieber, Holger Mickler, Matthias S Müller, and Wolfgang E Nagel. 2008. The vampir performance analysis tool-set. In Tools for High Performance Computing: Proceedings of the 2nd International Workshop on Parallel Tools for High Performance Computing, July 2008, HLRS, Stuttgart. Springer, 139–155. [17] Shang Li, Zhiyuan Yang, Dhiraj Reddy, Ankur Srivastava, and Bruce Jacob. 2020. DRAMsim3: A cycle-accurate, thermal-capable DRAM simulator. IEEE Computer Architecture Letters 19, 2 (2020), 106–109. [18] Jason Lowe-Power, Abdul Mutaal Ahmad, Ayaz Akram, Mohammad Alian, Rico Amslinger, Matteo Andreozzi, Adrià Armejach, Nils Asmussen, Brad Beckmann, Srikant Bharadwaj, et al. 2020. The gem5 simulator: Version 20.0+. arXiv preprint arXiv:2007.03152 (2020). [19] Haocong Luo, Yahya Can Tuğrul, F Nisa Bostancı, Ataberk Olgun, A Giray Yağlıkçı, and Onur Mutlu. 2023. Ramulator 2.0: A modern, modular, and extensible dram simulator. IEEE Computer Architecture Letters 23, 1 (2023), 112–116. [20] John Mellor-Crummey, Robert J Fowler, Gabriel Marin, and Nathan Tallent. 2002. HPCView: A tool for top-down analysis of node performance. The Journal of Supercomputing 23, 1 (2002), 81–104. [21] Kaushal Mhapsekar, Azam Ghanbari, Bita Aslrousta, and Samira MirbagherAjorpaz. 2026. CacheMind: From Miss Rates to Why-Natural-Language, TraceGrounded Reasoning for Cache Replacement. In Proceedings of the 31st ACM International Conference on Architectural Support for Programming Languages and Operating Systems, Volume 2. 307–322. [22] NVIDIA Corporation. 2025. NVIDIA Nsight Compute. https://developer.nvidia. com/nsight-compute. Accessed October 2025. 13

Record · ID 370400 · SHA-256 5b009a207fd4da10
Retrieved via Conceptio — every document is proof-bundled with source, license, and retrieval metadata.