← SEARCHABLE ARCHIVE
C / C++ · 2026-08-15

C++ von den Grundlagen bis zum Profi — Folge 22

Speicherkosten mit Datenlayout, Caches und pmr gestalten

INTERACTIVE READING MODE →

Die Artikel in diesem Blog wurden zu Lehrzwecken verfasst. Sie können Fehler enthalten; prüfen Sie die Aussagen daher mit dem Ziel-Compiler und der verwendeten Standardbibliothek.

Performance hängt nicht nur von der Anzahl der Operationen ab. Objektlayout, Zugriffsreihenfolge und Allokationshäufigkeit beeinflussen CPU-Cache und Durchsatz.

Zusammenhängende Daten nutzen Caches leichter

struct Particle
{
    float X, Y, Z;
    float VelocityX, VelocityY, VelocityZ;
    bool Active;
};

std::vector<Particle> particles;

Ein Array of Structures ist einfach und lokal, wenn ein Durchlauf fast alle Felder benutzt. Ein Positions-Update lädt möglicherweise trotzdem ungenutzte Felder in die Cache-Line.

struct ParticlePositions
{
    std::vector<float> X, Y, Z;
};

Eine Structure of Arrays hält gleiche Felder zusammen und kann SIMD sowie Massenverarbeitung unterstützen. Operationen auf einem vollständigen Objekt werden dafür komplexer.

Allokation nach Lebensdauer gestalten

std::array<std::byte, 4096> buffer;
std::pmr::monotonic_buffer_resource arena(buffer.data(), buffer.size());
std::pmr::vector<std::pmr::string> names(&arena);

names.emplace_back("Knight");
names.emplace_back("Mage");

PMR-Container erhalten ihre Memory Resource zur Laufzeit. Eine monotonic_buffer_resource allokiert vorwärts und gibt alles gemeinsam frei. Das passt zu temporären Daten mit gleicher Lebensdauer.

Die Resource muss länger leben als alle verwendenden Container und Elemente. Wird die Arena zuerst zerstört, verweisen sie auf ungültigen Speicher.

reserve ist eine Reallokationsstrategie

std::vector<Entity> entities;
entities.reserve(expectedCount);

Bei bekannter Größe reduziert reserve wiederholte Allokationen und Moves. Eine zu große Schätzung bindet ungenutzten Speicher. Reallokation invalidiert Adressen und Iteratoren; für langfristige Referenzen eignen sich eventuell Indizes oder Handles mit Generation.

Ändern Sie Layout nicht ohne Messung. Vergleichen Sie repräsentative Workloads nach wall time, CPU time, Allokationen, peak memory und cache misses und prüfen Sie die Korrektheit erneut.

Gutes Speicherdesign bedeutet nicht den cleversten Allocator, sondern klare Lebensdauer und Zugriffsmuster mit dem einfachsten Besitzmodell, das das Messziel erreicht.