Skip to content

Alocação de Memória Dinâmica

A alocação de memória dinâmica é uma prática que permite aos programadores alocar e desalocar memória durante a execução do programa. Quando lidamos com grandes volumes de dados e operações computacionalmente intensivas, a gestão eficiente da memória é crucial para o desempenho e a escalabilidade das aplicações.

Em C++, a memória dinâmica é gerenciada usando os operadores new e delete para alocar e desalocar memória, respectivamente.

Exemplo 1: Alocação e Manipulação de Matrizes Dinâmicas

Vamos considerar um exemplo de alocação dinâmica de uma matriz e sua utilização em operações de HPC.

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main() {
    int N = 1000; // Tamanho da matriz

    // Aloca memória para uma matriz dinâmica
    int** matriz = new int*[N];
    for (int i = 0; i < N; ++i) {
        matriz[i] = new int[N];
    }

    // Inicializa a matriz com valores
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            matriz[i][j] = i + j;
        }
    }

    // Realiza uma operação de soma simples na matriz
    auto inicio = high_resolution_clock::now();
    long long soma = 0;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            soma += matriz[i][j];
        }
    }
    auto fim = high_resolution_clock::now();
    auto duracao = duration_cast<milliseconds>(fim - inicio).count();

    cout << "Soma de todos os elementos: " << soma << endl;
    cout << "Tempo de execução: " << duracao << "ms" << endl;

    // Libera a memória alocada para a matriz
    for (int i = 0; i < N; ++i) {
        delete[] matriz[i];
    }
    delete[] matriz;

    return 0;
}

Alocação da Matriz:

  • int** matriz = new int*[N]; aloca memória para um array de ponteiros.
  • O loop for interno aloca memória para cada linha da matriz.
  • Inicialização e Operações:
    • A matriz é inicializada com a soma dos índices.
    • Realiza uma operação de soma em todos os elementos da matriz, medindo o tempo de execução.
  • Desalocação da Memória:
    • A memória alocada para cada linha é liberada usando delete[].
    • A memória alocada para o array de ponteiros é liberada usando delete[].

Alocação de Memória com std::vector

Usar std::vector é uma alternativa eficiente e segura para a alocação de memória dinâmica manual em C++. std::vector gerencia automaticamente a memória, reduzindo o risco de vazamentos de memória e outros erros.

Exemplo com std::vector

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

using namespace std;
using namespace std::chrono;

int main() {
    int N = 1000; // Tamanho da matriz

    // Aloca memória para uma matriz dinâmica usando std::vector
    vector<vector<int>> matriz(N, vector<int>(N));

    // Inicializa a matriz com valores
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            matriz[i][j] = i + j;
        }
    }

    // Realiza uma operação de soma simples na matriz
    auto inicio = high_resolution_clock::now();
    long long soma = 0;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            soma += matriz[i][j];
        }
    }
    auto fim = high_resolution_clock::now();
    auto duracao = duration_cast<milliseconds>(fim - inicio).count();

    cout << "Soma de todos os elementos: " << soma << endl;
    cout << "Tempo de execução: " << duracao << "ms" << endl;

    return 0;
}

Considerações de Desempenho em HPC

  1. Localidade de Dados:
    • A localidade de referência é importante para o desempenho da cache. Matrizes alocadas dinamicamente podem ter menor localidade de referência do que matrizes estáticas ou std::vector, especialmente se cada linha for alocada separadamente.
  2. Fragmentação de Memória:
    • A alocação dinâmica pode levar à fragmentação de memória, especialmente se a memória for alocada e desalocada frequentemente. Isso pode ser mitigado usando pools de memória ou alocadores personalizados.
  3. Parallelismo:
    • Alocação de memória dinâmica pode introduzir sobrecarga em ambientes paralelos devido à necessidade de sincronização. Em HPC, é comum usar técnicas avançadas para gerenciar a alocação de memória de forma eficiente em ambientes paralelos.

A alocação de memória dinâmica é uma prática fundamental em C++ que permite gerenciar a memória de forma flexível durante a execução do programa. No contexto de HPC, a gestão eficiente da memória é crucial para o desempenho e a escalabilidade das aplicações. Usar técnicas como alocação manual com new e delete ou alocação automática com std::vector pode ajudar a escrever código eficiente e seguro.