Analyze an Instruction Trace with Latency, Throughput, Cache, and Roofline Constraints
ImcHardware Engineer · OnsiteLast updated
Implement a pipeline simulation that calculates total execution cycles under RAW data hazards and computes roofline bottleneck metrics for a given instruction trace.
Problem Description
Modern hardware performance analysis often involves tracking pipeline latency bottlenecks and comparing achieved performance against theoretical ceilings using the Roofline model.
Implement a function analyze_trace that simulates the execution of an in-order, single-issue processor core with Read-After-Write (RAW) data hazard stalls, and calculates roofline metrics for the workload.
Pipeline Execution Rules
- Instructions issue in-order, at most one per cycle. The first instruction issues at cycle
0. - An instruction
ican only issue at cycleTif:T >= T_prev + 1(whereT_previs the issue cycle of instructioni - 1).- For every register
rinsources,T >= ready_cycle[r], whereready_cycle[r]is the cycle at which the instruction writing torcompletes execution.
- If an instruction issues at cycle
Twith latencyL, it completes at cycleT + L. If it defines adestregister,ready_cycle[dest] = T + L. - The total execution time is the completion cycle of the last instruction to finish.
Roofline Model
- Total FLOPs is the sum of
flopsacross all instructions. - Total memory traffic is the sum of
bytes_transferredacross all instructions. arithmetic_intensity = total_flops / total_bytes(return0.0iftotal_bytes == 0).roofline_ceiling = min(peak_compute, arithmetic_intensity * peak_bandwidth).limiting_factoris"Compute-Bound"ifpeak_compute <= arithmetic_intensity * peak_bandwidth, otherwise"Memory-Bound".
Function Signature
def analyze_trace(
trace: list[tuple[str, str | None, list[str], int, int]],
latencies: dict[str, int],
peak_compute: float,
peak_bandwidth: float,
) -> dict:
pass
Each element in trace is a tuple: (op, dest, sources, bytes_transferred, flops).
Output Format
Return a dictionary with keys:
"total_cycles": int"arithmetic_intensity": float"roofline_ceiling": float"limiting_factor": str ("Compute-Bound"or"Memory-Bound")
Example
trace = [
("LOAD", "R1", [], 8, 0),
("LOAD", "R2", [], 8, 0),
("FADD", "R3", ["R1", "R2"], 0, 1),
("FMUL", "R4", ["R3", "R3"], 0, 1),
("STORE", None, ["R4"], 8, 0),
]
latencies = {"LOAD": 3, "STORE": 1, "FADD": 2, "FMUL": 3}
peak_compute = 2.0 # FLOPs/cycle
peak_bandwidth = 16.0 # Bytes/cycle
result = analyze_trace(trace, latencies, peak_compute, peak_bandwidth)
# Returns:
# {
# "total_cycles": 10,
# "arithmetic_intensity": 0.08333333333333333, # 2 FLOPs / 24 Bytes
# "roofline_ceiling": 1.3333333333333333, # min(2.0, 0.0833 * 16.0)
# "limiting_factor": "Memory-Bound"
# }
Cycle trace breakdown for the example:
- Inst 0 (
LOAD): Issues cycle 0, finishes cycle 3 (R1ready at 3). - Inst 1 (
LOAD): Issues cycle 1, finishes cycle 4 (R2ready at 4). - Inst 2 (
FADD): NeedsR1(ready 3) andR2(ready 4). Issues cycle 4, finishes cycle 6 (R3ready at 6). - Inst 3 (
FMUL): NeedsR3(ready 6). Issues cycle 6, finishes cycle 9 (R4ready at 9). - Inst 4 (
STORE): NeedsR4(ready 9). Issues cycle 9, finishes cycle 10. - Trace completes at cycle 10.
Hints
Hint 1
Track the availability cycle for each register in a hash map, initializing registers not yet written to cycle 0.
Hint 2
For each instruction, the earliest valid issue cycle is max(prev_issue_cycle + 1, max(ready_cycles of all source registers)).
Hint 3
Remember that total execution time is determined by the maximum completion cycle across all instructions, which may not always be the issue cycle + latency of the final instruction.
Follow-up questions
- How would you extend this simulation to support an out-of-order superscalar pipeline with register renaming?
- If profiling showed this kernel was memory-bound on actual hardware, what software transformations (e.g., loop tiling, register reuse) would increase arithmetic intensity?
- How does cache line utilization affect the effective memory bandwidth in the roofline model compared to theoretical peak bandwidth?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.