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

C++ de los fundamentos al dominio — Lección 22

Diseñar el coste de memoria con disposición de datos, cachés y pmr

INTERACTIVE READING MODE →

Los artículos de este blog se han escrito con fines didácticos. Pueden contener errores; contrasta la información con el compilador y la biblioteca estándar de tu plataforma.

El rendimiento no depende solo del número de operaciones. La disposición de objetos, el orden de acceso y la frecuencia de asignación afectan a la caché y al throughput.

Los datos contiguos aprovechan la caché

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

std::vector<Particle> particles;

Un Array of Structures es simple y local cuando cada paso usa casi todos los campos. Si solo actualiza posiciones, puede cargar campos no usados en la cache line.

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

Una Structure of Arrays mantiene campos iguales contiguos y puede ayudar a SIMD y al procesamiento masivo, a costa de complicar operaciones sobre una partícula completa.

Diseñar la asignación según la vida útil

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");

Los contenedores PMR reciben su memory resource en ejecución. monotonic_buffer_resource asigna hacia delante y libera todo junto, apropiado para datos temporales con una vida compartida.

El resource debe vivir más que cada contenedor y elemento que lo usa. Destruir antes el arena deja referencias a memoria inválida.

reserve es una política de reasignación

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

Con un tamaño esperado, reserve evita asignaciones y movimientos repetidos. Una estimación excesiva retiene memoria sin usar. La reasignación invalida direcciones e iteradores; las referencias duraderas pueden requerir índices o handles con generación.

No cambies el layout sin medir. Compara workloads representativos mediante wall time, CPU time, asignaciones, peak memory y cache misses, y vuelve a comprobar la corrección.

Un buen diseño de memoria no usa el allocator más ingenioso. Expresa vidas y patrones de acceso y elige el modelo de propiedad más simple que cumpla el objetivo medido.