TLB Experiments

What You'll Learn

Experiment: One Access Per Page

Access one element per page to force TLB usage:

#include <chrono>
#include <iostream>
#include <vector>

using Clock = std::chrono::high_resolution_clock;
using Duration = std::chrono::nanoseconds;

const size_t PAGE_SIZE = 4096;  // 4 KB pages

double measure_tlb_effect(size_t num_pages) {
    size_t total_size = num_pages * PAGE_SIZE;
    std::vector<char> data(total_size, 1);
    
    volatile int sum = 0;
    const int iterations = 100000;
    
    auto start = Clock::now();
    for (int i = 0; i < iterations; ++i) {
        // Access one element per page
        for (size_t page = 0; page < num_pages; ++page) {
            size_t idx = page * PAGE_SIZE;
            sum += data[idx];
        }
    }
    auto end = Clock::now();
    
    auto elapsed = std::chrono::duration_cast<Duration>(end - start);
    return static_cast<double>(elapsed.count()) / (iterations * num_pages);
}

int main() {
    std::cout << "Pages\tAccess Time (ns)\n";
    for (size_t pages = 1; pages <= 1024; pages *= 2) {
        double time = measure_tlb_effect(pages);
        std::cout << pages << "\t" << time << "\n";
    }
    return 0;
}

What to Measure

Expected Shape of Results

You should see a step-like curve:

Interpretation

When the number of pages exceeds TLB capacity, each new page access causes a TLB miss and page-walk. The latency jump is the cost of those page-walks.

Checklist