Cache Effect

The Hidden Cost of Memory Misses

Diagnosing Cache Allocation Issues
with Eclipse Trace Compass

(Trace Compass · Trace Event Logger · Linux Tracing Landscape)

Matthew Khouzam & Anh Nguyen | Ericsson Canada | TheiaCon 2025 (Thrilled to be here)

Problem Statement

  • We explore cache size effects on performance & KPIs.
  • Why do dashboards look green while the app feels slow?
  • Tracing reveals hidden stalls & contention.

Deep Dive Tools

Two key tools for our cache analysis journey:

  • Trace Compass - Visualization & analysis
  • Trace Event Logger - Java instrumentation

Trace Compass

  • Rich visualization capabilities
  • Cross-stack correlation
  • Extensible analysis framework
  • Perfect for understanding complex interactions

Trace Event Logger

  • Java-oriented tracing
  • Lightweight, easy to integrate
  • Inspired by UST, simpler developer experience
  • Minimal code changes required

Who Are We?

Matthew Khouzam

  • Tracing & performance enthusiast
  • Contributor/Maintainer/Co-Lead/Product Owner to some open source tracing tools
  • Experience diagnosing real-world performance issues

Anh Nguyen

  • Software intern & performance analyst
  • Tracing tools developer
  • Open source contributor
  • aaanh.com

Ericsson & Tracing

  • Active contributor to open tracing ecosystems for over 15 years
  • Academic partner to Ecole Polytechnique Montreal and many industries
  • Supports development of Trace Compass
  • Internally used for software and hardware troubleshooting
  • Helps industry adopt tracing in production
  • Allows me to make the world a better place through FOSS

Tracing Landscape

There are more!

Linux Kernel

  • Ftrace
  • LTTng Kernel
  • Perf / eBPF

Linux Userspace

  • LTTng UST
  • UProbes
  • UFtrace

Windows

  • ETW (Event Tracing for Windows)
  • WPA (Windows Performance Analyzer)
  • PerfView

macOS

  • DTrace
  • Instruments
  • OSLog

Java

  • LTTng UST Java Agent
  • JFR (Java Flight Recorder)
  • Trace Event Logger

TypeScript

  • OpenTelemetry JS: Industry standard, comprehensive but heavy
  • Chrome DevTools: Built-in profiling, limited to browser context
  • Node.js --inspect: V8 profiler integration, good for CPU/memory
  • Custom JSON tracers: Lightweight, Trace Compass compatible
  • Gap: No native equivalent to UST/Trace Event Logger simplicity

Visualization Tools

  • Command Line: perf, trace-cmd
  • Open Telemetry: High-level, great down to the uS!
  • Perfetto: beautiful, web-based, Chrome/Android focus
  • KernelShark: kernel views, scheduler focus
  • Trace Compass: unified analysis

Trace Event Logger

  • Designed for Java tracing
  • UST-inspired
  • Lightweight & easy integration
  • Trade-off: fewer features than UST
Type View
Scope An image showing a scope event view, represented as a block on a timeline.
Flow An image showing a flow event view, represented as an arrow connecting two points on different timelines.
Counter An image showing a counter event view, represented as a line graph plotting a value over time.
Lifespan An image showing an object lifespan view, represented as a block on a timeline that starts and ends.

Tracing Semantics

  • Important to define what you trace
  • Placement & granularity change results
  • Avoid misleading conclusions from partial data

TypeScript Instrumentation

  • Similar approach to Trace Event Logger
  • Generate compatible JSON output
  • Lightweight & easy integration

Original TypeScript Code


import * as fs from 'fs';

export class CacheProcessor {
    async processData(data: string[]): Promise {
        console.log("Processing data batch");
        
        for (const item of data) {
            await this.processItem(item);
        }
        
        await fs.promises.writeFile('output.txt', data.join('\n'));
    }
}
          

Instrumented TypeScript Code


 import * as fs from 'fs';
+import { TraceLogger } from './trace-logger';

 export class CacheProcessor {
+    private tracer = new TraceLogger();
+    
     async processData(data: string[]): Promise {
         console.log("Processing data batch");
+        const span = this.tracer.startScope('processData', { count: data.length });
         
         for (const item of data) {
             await this.processItem(item);
         }
         
         await fs.promises.writeFile('output.txt', data.join('\n'));
+        span.end();
     }
 }
          

Simple Trace Logger Implementation


export class TraceLogger {
    private events: any[] = [];
    
    startScope(name: string, args?: any) {
        const start = Date.now() * 1000; // microseconds
        const event = {
            name, ph: 'B', ts: start, pid: process.pid, 
            tid: 0, args: args || {}
        };
        this.events.push(event);
        
        return {
            end: () => {
                this.events.push({
                    ...event, ph: 'E', ts: Date.now() * 1000
                });
            }
        };
    }
    
    writeTrace(filename: string) {
        fs.writeFileSync(filename, JSON.stringify(this.events));
    }
}
          

Trace Compass Design

  • Modular architecture
  • State system & analysis engines
  • Extensible for custom views

Extension frontend architecture

Continuously porting over features to the extension!

...where one of the latest addition is the Flame Graph

Flame Charts & Graphs

  • Flame Graph: aggregated profiles
  • Flame Chart: time-aligned stacks
  • Complementary perspectives on performance

Flame Graph - Aggregated View

  • What: Stack traces collapsed and sorted by frequency
  • X-axis: Percentage of samples (width = time spent)
  • Y-axis: Call stack depth
  • Best for: Finding hotspots, CPU-bound bottlenecks
  • Loses: Temporal information, execution order

Flame Chart - Timeline View

  • What: Stack traces over time, preserving chronology
  • X-axis: Time progression
  • Y-axis: Call stack depth
  • Best for: Understanding execution flow, cache misses, I/O waits
  • Shows: When things happen, duration patterns

Why Both Matter for Cache Analysis

  • Flame Graph: "Which functions are slow overall?"
  • Flame Chart: "When do cache misses cause stalls?"
  • Cache issues often show as temporal patterns
  • Aggregation can hide intermittent problems

Flame Chart in action

A better explanation

https://youtu.be/gDe77bVkv50

🎉 New: VS Code Trace Extension

  • Trace Compass analysis now available in VS Code!
  • Killer feature: Flame graphs + flame charts correlation
  • Same powerful backend, modern IDE experience

Example Project

A cache with many threads reading from it:

  • Artificially constrained cache size
  • Threads compete for cache access
  • Performance seems fine at first glance

Deceptive KPIs

  • Latency metrics: ✅
  • Throughput metrics: ✅
  • User experience: ❌ (super slow)
Tracing exposes the hidden story behind “green dashboards”.

Instrumentation Strengths

  • Static instrumentation = always available
  • Low overhead, high precision
  • Minimal perturbation to workload
Code examples below.

Original Code


import java.io.FileWriter;

public class SlappyWag {
    public static void main(String[] args) {
        System.out.println("The program will write hello 10x between two scope logs\n");
        try (FileWriter fw = new FileWriter("test.txt")) {
            for (int i = 0; i < 10; i++) {
                fw.write("Hello world "+ i);
            }
        }
    }
}
          

Instrumented Code


import java.io.FileWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.tracecompass.traceeventlogger.LogUtils;

public class SlappyWag {
    
    private static Logger logger = Logger.getAnonymousLogger();
    
    public static void main(String[] args) {
        System.out.println("The program will write hello 10x between two scope logs\n");
        try (LogUtils.ScopeLog sl = new LogUtils.ScopeLog(logger, Level.FINE, "writing to file"); FileWriter fw = new FileWriter("test.txt")) {
            for (int i = 0; i < 10; i++) {
                fw.write("Hello world "+ i);
            }
        }
    }
}
          

Code Results

  • Traces reveal delays at cache boundaries
  • Clear visualization of synchronous stalls
Scroll down!

Overview

In depth

The Cache Miss Story

  • Synchronous cache misses = correctness intact
  • But waiting destroys performance
  • Tracing shows cause, not just symptom

Breather

Takeaways

  • High-level KPIs can be misleading
  • Tracing reveals hidden bottlenecks
  • Cache effects must be contextualized
  • Trace Compass + Trace Event Logger = deep insight

Questions?

Let’s discuss your own “good KPIs, bad performance” stories.

PS We have references

https://tracecompass.org Our Youtube channel https://www.youtube.com/@EclipseTraceCompass

PPS We want to collaborate!