Optimisation de la mémoire
Stratégies d'efficacité mémoire en C++
L'optimisation de la mémoire est essentielle pour le développement d'applications hautes performances. Cette section explore des techniques avancées pour minimiser la surcharge mémoire et améliorer l'utilisation des ressources.
Optimisation de la disposition mémoire
graph TD
A[Optimisation mémoire] --> B[Structures compactes]
A --> C[Allocation efficace]
A --> D[Minimisation de la surcharge]
B --> E[Alignement des données]
C --> F[Piscines mémoire]
D --> G[Pointeurs intelligents]
Emballage des structures
// Disposition mémoire inefficace
struct LargeStruct {
char a; // 1 octet
int b; // 4 octets
double c; // 8 octets
}; // Typiquement 16 octets
// Disposition mémoire optimisée
struct __attribute__((packed)) CompactStruct {
char a; // 1 octet
int b; // 4 octets
double c; // 8 octets
}; // Précisément 13 octets
Techniques d'allocation mémoire
Implémentation de piscine mémoire
class MemoryPool {
private:
std::vector<char*> blocks;
const size_t blockSize;
public:
void* allocate(size_t size) {
// Logique d'allocation mémoire personnalisée
char* block = new char[size];
blocks.push_back(block);
return block;
}
void deallocateAll() {
for (auto block : blocks) {
delete[] block;
}
blocks.clear();
}
};
Stratégies d'optimisation
| Stratégie |
Description |
Impact sur les performances |
| Optimisation des objets petits |
Stockage intégré pour les petits objets |
Réduit les allocations mémoire heap |
| Placement New |
Placement mémoire personnalisé |
Minimise la surcharge d'allocation |
| Piscines mémoire |
Blocs mémoire préalloués |
Réduit la fragmentation |
Exemple d'optimisation des objets petits
template <typename T, size_t InlineSize = 16>
class SmallVector {
alignas(T) char inlineStorage[InlineSize * sizeof(T)];
T* dynamicStorage = nullptr;
size_t currentSize = 0;
public:
void push_back(const T& value) {
if (currentSize < InlineSize) {
// Utilisation du stockage intégré
new (inlineStorage + currentSize * sizeof(T)) T(value);
} else {
// Retour à l'allocation dynamique
dynamicStorage = new T[currentSize + 1];
}
++currentSize;
}
};
Gestion mémoire avancée
Allocateur personnalisé avec suivi
template <typename T>
class TrackingAllocator {
private:
size_t totalAllocated = 0;
public:
T* allocate(size_t n) {
totalAllocated += n * sizeof(T);
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void reportMemoryUsage() {
std::cout << "Mémoire totale allouée : "
<< totalAllocated << " octets" << std::endl;
}
};
#include <chrono>
#include <memory>
void benchmarkMemoryAllocation() {
auto start = std::chrono::high_resolution_clock::now();
// Test d'allocation mémoire
std::unique_ptr<int[]> largeBuffer(new int[1000000]);
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << "Temps d'allocation : " << duration.count() << " microsecondes" << std::endl;
}
Recommandations LabEx
Chez LabEx, nous soulignons que l'optimisation de la mémoire est un art. Continuez à profiler, à mesurer et à affiner vos stratégies de gestion de la mémoire pour atteindre des performances optimales.