Skip to content

Memory Prediction Module

Module: 08_09_01_memory_prediction Phase: FASE 2 - Memory Prediction Status: ✅ Complete

Overview

The Memory Prediction module provides comprehensive memory analysis tools for audio processing components, covering stack usage, heap allocations, and memory layout optimization. Essential for embedded systems, real-time safety validation, and performance optimization.

Features

🎯 Core Capabilities

  • Stack Usage Calculation - Static analysis of stack memory requirements
  • Heap Allocation Detection - Runtime and static detection of allocations
  • Memory Layout Optimization - Struct/class layout analysis and optimization
  • Cache Line Analysis - Cache utilization and false sharing detection
  • Real-Time Safety - Validation of RT constraints

📊 Analysis Types

Analysis Type Tool Use Case
Stack StackUsageCalculator Embedded systems, RT budgets
Heap HeapAllocationDetector RT safety validation
Layout MemoryLayoutOptimizer Performance optimization
Cache MemoryLayoutOptimizer False sharing prevention

Architecture

08_09_01_memory_prediction/
├── include/
│   ├── StackUsageCalculator.hpp       # Stack usage analysis
│   ├── HeapAllocationDetector.hpp     # Heap allocation tracking
│   └── MemoryLayoutOptimizer.hpp      # Layout optimization
├── src/
│   ├── StackUsageCalculator.cpp
│   ├── HeapAllocationDetector.cpp
│   └── MemoryLayoutOptimizer.cpp
├── tests/
│   └── test_memory_prediction.cpp     # Catch2 tests
├── examples/
│   └── memory_prediction_demo.cpp     # Complete demos
└── CMakeLists.txt

Quick Start

1. Stack Usage Analysis

#include <StackUsageCalculator.hpp>

using namespace audiolab::plugins::profiling;

StackUsageCalculator calculator;

// Analyze component
auto profile = calculator.analyzeComponent("reverb", "reverb_algorithmic");

std::cout << "Stack usage: " << profile.total << " bytes\n";
std::cout << "Max depth: " << profile.maxDepth << "\n";

// Check budget
auto check = calculator.checkBudget(StackBudgets::EMBEDDED_MEDIUM);

if (!check.withinBudget) {
    std::cerr << "Exceeds stack budget!\n";
}

2. Heap Allocation Detection

#include <HeapAllocationDetector.hpp>

HeapAllocationDetector detector;

// Mark real-time context
void audioCallback() {
    ScopedRealtimeContext rtGuard(detector);

    // Any allocations here will be flagged as violations
    processAudio();
}

// Check violations
if (detector.getRealtimeViolationCount() > 0) {
    std::cerr << detector.generateViolationReport();
}

3. Memory Layout Optimization

#include <MemoryLayoutOptimizer.hpp>

MemoryLayoutOptimizer optimizer;

// Define struct fields
std::vector<MemoryLayoutOptimizer::FieldDef> fields = {
    {"bool", "bypass", 1},
    {"float", "gain", 4},
    {"double", "sampleRate", 8},
    {"int", "bufferSize", 4}
};

// Optimize layout
auto optimized = optimizer.optimizeLayout("ProcessorState", fields);

std::cout << "Bytes saved: " << optimized.bytesSaved << "\n";
std::cout << "Improvement: " << optimized.improvementPercent << "%\n";
std::cout << "\nOptimized code:\n" << optimized.generatedCode;

Stack Usage Calculator

Features

  • Static Cost Analysis - Estimate stack usage without runtime profiling
  • Component Models - Built-in models for common audio components
  • Call Depth Tracking - Maximum function call depth analysis
  • Recursive Detection - Identify recursive functions
  • Budget Validation - Check against embedded/desktop budgets

Stack Budgets

namespace StackBudgets {
    constexpr size_t EMBEDDED_TINY = 1024;       // 1 KB - Microcontrollers
    constexpr size_t EMBEDDED_SMALL = 4096;      // 4 KB - ARM Cortex-M
    constexpr size_t EMBEDDED_MEDIUM = 16384;    // 16 KB - Embedded Linux
    constexpr size_t DESKTOP_SAFE = 65536;       // 64 KB - Desktop safe
    constexpr size_t DESKTOP_NORMAL = 262144;    // 256 KB - Typical desktop
}

Usage Example

StackUsageCalculator calc;

// Analyze plugin components
std::vector<std::string> ids = {"filter", "comp", "reverb"};
std::vector<std::string> types = {
    "filter_biquad", "compressor_rms", "reverb_algorithmic"
};

auto profiles = calc.analyzePlugin(ids, types);

// Get top stack users
auto top3 = calc.getTopStackUsers(3);

for (const auto& [id, usage] : top3) {
    std::cout << id << ": " << usage << " bytes\n";
}

// Check budget
auto check = calc.checkBudget(StackBudgets::EMBEDDED_MEDIUM);
std::cout << "Utilization: " << (check.utilization * 100) << "%\n";

Heap Allocation Detector

Features

  • Static Analysis - Scan source files for allocation patterns
  • Runtime Tracking - Track allocations in dev/test builds
  • Real-Time Context - Mark RT threads for violation detection
  • Pattern Detection - Find new, malloc, STL containers, smart pointers
  • Component Breakdown - Per-component allocation summary

Allocation Types Detected

enum class Type {
    New,                // operator new
    NewArray,           // operator new[]
    Malloc,             // malloc/calloc/realloc
    STLContainer,       // std::vector, std::map, etc.
    SmartPointer,       // std::make_shared/unique
    Unknown
};

Real-Time Safety Example

HeapAllocationDetector detector;

// Init phase (allocations allowed)
detector.trackAllocation("prepare", 8192, AllocationInfo::Type::NewArray);

// Audio callback (NO allocations allowed)
void processBlock() {
    ScopedRealtimeContext rt(detector);

    // Clean RT code here
    // Any allocation triggers violation
}

// Check violations
if (detector.getRealtimeViolationCount() > 0) {
    std::cerr << "❌ RT Safety Violated!\n";
    std::cerr << detector.generateViolationReport();
}

Component Summary

auto summary = detector.getComponentSummary("reverb");

std::cout << "Component: " << summary.componentId << "\n";
std::cout << "Total allocations: " << summary.totalAllocations << "\n";
std::cout << "Total bytes: " << summary.totalBytes << "\n";
std::cout << "RT violations: " << summary.realtimeViolations << "\n";

Memory Layout Optimizer

Features

  • Padding Analysis - Identify wasted padding bytes
  • Field Reordering - Suggest optimal field ordering
  • Cache Line Optimization - Align hot data to cache boundaries
  • False Sharing Detection - Prevent cross-core cache conflicts
  • Code Generation - Generate optimized struct definitions

Layout Analysis

MemoryLayoutOptimizer optimizer;

std::vector<MemoryLayoutOptimizer::FieldDef> fields = {
    {"bool", "bypass", 1},
    {"float", "gain", 4},
    {"int", "mode", 4},
    {"double", "phase", 8}
};

auto analysis = optimizer.analyzeLayout("State", fields);

std::cout << "Total size: " << analysis.totalSize << "\n";
std::cout << "Padding waste: " << analysis.paddingSize << "\n";
std::cout << "Efficiency: " << (analysis.efficiency * 100) << "%\n";

Optimization Workflow

// 1. Analyze original layout
auto original = optimizer.analyzeLayout("ProcessorState", fields);

// 2. Get optimized layout
auto optimized = optimizer.optimizeLayout("ProcessorState", fields);

std::cout << "Bytes saved: " << optimized.bytesSaved << "\n";
std::cout << "Improvement: " << optimized.improvementPercent << "%\n";

// 3. Use generated code
std::cout << optimized.generatedCode;
// Output:
// struct ProcessorState_Optimized {
//     double phase;      // 8-byte aligned first
//     float gain;
//     int mode;
//     bool bypass;
// };

Cache Line Analysis

auto cache = optimizer.analyzeCacheUtilization("HotStruct", fields);

std::cout << "Cache lines used: " << cache.cacheLinesUsed << "\n";

if (cache.falseSharingRisk) {
    std::cout << "⚠️  False sharing risk!\n";
    for (const auto& field : cache.falseSharingFields) {
        std::cout << "  - " << field << "\n";
    }
}

if (cache.splitAcrossCacheLines) {
    std::cout << "⚠️  Fields split across cache lines:\n";
    for (const auto& field : cache.splitFields) {
        std::cout << "  - " << field << "\n";
    }
}

False Sharing Prevention

// Bad: Multiple atomics in same cache line
struct BadCounter {
    std::atomic<int> counter1;  // Cache line 0
    std::atomic<int> counter2;  // Cache line 0 - FALSE SHARING!
};

// Good: Separate cache lines
struct alignas(64) GoodCounter {
    std::atomic<int> counter1;
    char padding[64 - sizeof(std::atomic<int>)];
};

Testing

Build and Run Tests

# Configure
cmake -B build -DBUILD_TESTING=ON

# Build
cmake --build build --config Release

# Run tests
cd build
ctest --output-on-failure

# Or run directly
./Release/test_memory_prediction.exe

Test Coverage

  • ✅ Stack usage analysis (all component types)
  • ✅ Manual stack tracking
  • ✅ Budget validation
  • ✅ Heap allocation detection (all types)
  • ✅ Real-time context tracking
  • ✅ Violation reporting
  • ✅ Layout analysis and optimization
  • ✅ Cache line analysis
  • ✅ False sharing detection
  • ✅ Code generation
  • ✅ Integration workflows

Examples

Run Demo

# Build
cmake --build build --config Release

# Run
./build/Release/memory_prediction_demo.exe

Demo Coverage

  1. Stack Usage - Component analysis, budget validation, top users
  2. Heap Allocation - Init vs RT phase, violation detection
  3. Memory Layout - Analysis, optimization, cache utilization
  4. Complete Workflow - Full memory analysis pipeline

Performance Characteristics

StackUsageCalculator

  • Complexity: O(n) where n = components
  • Memory: O(n) profile storage
  • Thread-safety: Read-only after analysis

HeapAllocationDetector

  • Complexity: O(1) per tracked allocation
  • Memory: O(m) where m = allocations (bounded by config)
  • Thread-safety: Safe for concurrent tracking

MemoryLayoutOptimizer

  • Complexity: O(n log n) for field reordering
  • Memory: Minimal (transient analysis)
  • Thread-safety: Stateless analysis (thread-safe)

Real-Time Safety

RT-Safe Operations

StackUsageCalculator::getTotalStackUsage() - Simple arithmetic ✅ StackUsageCalculator::getComponentProfile() - Map lookup ✅ HeapAllocationDetector::trackAllocation() - Vector push (pre-reserved)

NOT RT-Safe

Report generation - String allocation ❌ Static analysis - File I/O ❌ Layout optimization - Vector sorting

Integration with Other Modules

08_09_01_memory_prediction
    ↓ (provides data to)
08_09_03_bottleneck_warnings (memory bottlenecks)
    ↓ (feeds)
08_09_04_optimization_suggestions (memory optimizations)

Best Practices

1. Stack Budget Selection

// Embedded systems - use conservative budgets
auto check = calc.checkBudget(StackBudgets::EMBEDDED_MEDIUM);

// Desktop - more relaxed
auto check = calc.checkBudget(StackBudgets::DESKTOP_SAFE);

2. Real-Time Validation

// Always validate RT threads in dev/test builds
#ifdef DEBUG
    ScopedRealtimeContext rtGuard(detector);
#endif
    processAudio();  // Will catch allocations in debug builds

3. Layout Optimization Priority

// Focus on hot paths first
if (analysis.efficiency < 0.75f) {
    // Optimize this struct
    auto opt = optimizer.optimizeLayout(name, fields);
}

4. False Sharing Prevention

// Separate frequently modified fields
struct alignas(64) RTSafeState {
    std::atomic<float> parameterValue;  // Own cache line
    char padding[64 - sizeof(std::atomic<float>)];

    // Cold data can share cache lines
    bool initialized;
    int version;
};

Common Patterns

Complete Memory Analysis

void analyzeComponent(const std::string& id, const std::string& type) {
    // 1. Stack analysis
    StackUsageCalculator stackCalc;
    auto stackProfile = stackCalc.analyzeComponent(id, type);

    // 2. Heap tracking
    HeapAllocationDetector heapDetector;
    heapDetector.beginRealtimeContext();
    // ... process ...
    heapDetector.endRealtimeContext();

    // 3. Layout optimization
    MemoryLayoutOptimizer layoutOpt;
    // ... analyze layouts ...

    // 4. Report
    std::cout << "Stack: " << stackProfile.total << " bytes\n";
    std::cout << "RT violations: " << heapDetector.getRealtimeViolationCount() << "\n";
}

Dependencies

  • C++20 - <atomic>, <optional>, <chrono>
  • Catch2 - Testing framework

Future Enhancements

  • DWARF debug info parsing for precise stack analysis
  • Address sanitizer integration
  • Valgrind massif integration
  • Memory pool analysis
  • Fragmentation tracking
  • Platform-specific optimizations (ARM, x86, Apple Silicon)

See Also


Module Status: ✅ FASE 2 Complete Next: FASE 3 - Hotspot Identification (08_09_02_hotspot_identification)