Skip to content

Commit 621eea1

Browse files
authored
Merge pull request #152 from gurusamyanandakuma-r/main
Rohit and Sharmila - Project blog added - closes #137
2 parents fe62c5e + 80585ec commit 621eea1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+12274
-0
lines changed

blogs/rohit/project/Project.html

Lines changed: 797 additions & 0 deletions
Large diffs are not rendered by default.

blogs/rohit/project/Project.qmd

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
title: "Machine Learning-Driven Memory Optimization for C++ Applications: A Python-Based Approach"
3+
author:
4+
- name: "Rohit Gurusamy Anandakumar"
5+
- name: "Sharmila Sivalingam"
6+
7+
format:
8+
html:
9+
toc: true
10+
---
11+
12+
13+
## Abstract
14+
15+
In memory-intensive C++ applications, optimizing memory usage is critical, especially in environments with limited resources. This project introduces a Python-based approach that leverages runtime profiling data and machine learning (ML) techniques to enhance memory efficiency. The approach utilizes a **RandomForestRegressor** ML model to predict memory bottlenecks by analyzing complex interactions in profiling data. By identifying patterns in memory allocation, access, and release, the tool applies targeted optimizations such as replacing inefficient memory allocation calls, reallocation strategies, and ensuring proper deallocation of memory. The results demonstrate significant reductions in memory footprint and peak memory usage, providing valuable insights for developers aiming to improve memory-intensive applications.
16+
17+
## Key Concepts
18+
19+
Before diving into the implementation details, let's clarify some important terms:
20+
21+
- **Memory Allocation:** Memory allocation refers to the process by which a program requests memory from the system to store data. Dynamic allocation (e.g., `malloc` in C++) is common in applications where memory needs are determined during runtime.
22+
23+
- **Peak Memory Usage:** Peak memory usage is the maximum amount of memory consumed by a program at any point during its execution. Minimizing peak usage is essential for avoiding crashes and improving performance in resource-constrained environments.
24+
25+
- **Memory Profiling:** Memory profiling involves analyzing how an application allocates and frees memory over time. Tools like Valgrind's Massif generate detailed reports on memory usage, helping identify inefficiencies or leaks.
26+
27+
## Goals
28+
29+
1. Identify and optimize memory bottlenecks in five example C++ programs.
30+
2. Implement a Python tool that processes profiling data, predicts inefficiencies, and applies memory optimizations.
31+
3. Evaluate the effectiveness of these optimizations empirically.
32+
33+
## Design and Implementation
34+
35+
### Step 1: Collecting Memory Profiling Data
36+
37+
#### Method
38+
39+
```{mermaid}
40+
%%{init: {"flowchart": {"htmlLabels": false}} }%%
41+
42+
%%| echo: false
43+
graph LR;
44+
A[Start Profiling] --> B[Run Program with Massif];
45+
B --> C[Generate Massif Output];
46+
C --> D[Analyze Output with ms_print];
47+
D --> E[Convert to CSV for Analysis];
48+
```
49+
50+
- To analyze memory usage, we used Valgrind's Massif tool:
51+
+ Install Valgrind: `sudo apt install valgrind`
52+
+ Compile C++ programs with debug information: `g++ -g -o example1 example1.cpp`
53+
+ Run with Massif: `valgrind --tool=massif ./example1`
54+
+ Analyze results: `ms_print massif.out.<pid>`
55+
+ Convert results to CSV for further analysis.
56+
57+
### Step 2: Building the Python Tool
58+
59+
The Python tool processes profiling data and optimizes memory usage through:
60+
61+
#### Input Data:
62+
63+
1. **Profiling Data**: Memory allocation, peak memory usage, and other metrics from Massif converted to CSV.
64+
2. **Source Code**: C++ programs requiring optimization.
65+
66+
#### Machine Learning Component:
67+
68+
We used a **RandomForestRegressor** to predict memory inefficiencies based on the profiling data. This ML model enabled accurate identification of memory bottlenecks by analyzing complex interactions between memory allocation and usage patterns.
69+
70+
##### RandomForestRegressor Algorithm
71+
72+
1. **Initialize Parameters**: Set the number of trees (n_trees) and other hyperparameters.
73+
2. **Bootstrap Sampling**: For each tree, draw a bootstrap sample from the original data.
74+
3. **Train Trees**: Train a decision tree on each bootstrap sample. Each node in the tree considers a random subset of features when splitting.
75+
4. **Aggregate Predictions**: For regression, average the predictions of all the trees in the forest.
76+
77+
<div style="text-align: center;">
78+
```{mermaid}
79+
%%{init: {"flowchart": {"htmlLabels": false}} }%%
80+
81+
graph TD;
82+
A[Start] --> B[Initialize Parameters];
83+
B --> C[Bootstrap Sampling];
84+
C --> D[Train Decision Tree];
85+
D --> E{Repeat for n Trees};
86+
E -- Yes --> C;
87+
E -- No --> F[Aggregate Predictions];
88+
F --> G[Output Prediction];
89+
```
90+
</div>
91+
92+
This block diagram represents the workflow of the **RandomForestRegressor**. Here’s a step-by-step explanation:
93+
94+
1. **Initialize Parameters**: Set the number of trees (`n_trees`) and other parameters like maximum depth, minimum samples per leaf, etc.
95+
2. **Bootstrap Sampling**: Create multiple bootstrap samples (random subsets with replacement) from the original dataset.
96+
3. **Train Decision Tree**: Train a decision tree on each bootstrap sample. During tree construction, each node selects a subset of features randomly and uses the best split among them.
97+
4. **Repeat for n Trees**: Repeat the bootstrap sampling and tree training for `n` trees.
98+
5. **Aggregate Predictions**: For each test sample, predict the outcome using all the trained trees and then average these predictions to get the final output.
99+
100+
#### Optimizations Implemented:
101+
102+
1. **Code Transformations**:
103+
- Replacing `malloc` with `calloc` for improved initialization.
104+
- Nullifying pointers after `free` to prevent dangling references.
105+
2. **Memory Simulations**:
106+
- Adjusting allocation and peak values to simulate optimized memory behavior.
107+
108+
#### Method
109+
110+
<div style="text-align: center;">
111+
```{mermaid}
112+
%%{init: {"flowchart": {"htmlLabels": false}} }%%
113+
%%| echo: false
114+
graph TD;
115+
A[Input CSV and C++ Source] --> B[Parse and Preprocess Data];
116+
B --> C[Feature Engineering];
117+
C --> D[Train RandomForest Regressor];
118+
D --> E[Predict Memory Bottlenecks];
119+
E --> F[Apply Code Transformations];
120+
F --> G[Simulate Optimized Profile];
121+
G --> H[Save Outputs];
122+
```
123+
</div>
124+
125+
- The Python tool processes profiling data and optimizes memory usage through:
126+
+ **Feature Engineering**: Calculating `Memory_Delta` (difference between allocated and freed memory) and `Memory_Utilization_Ratio` (allocated memory divided by peak memory).
127+
+ **Source Code Optimization**: Replacing `malloc` with `calloc` and ensuring proper nullification after freeing memory.
128+
+ **Simulated Profiling**: Adjusting allocation and peak memory values to simulate optimization effects.
129+
130+
### Step 3: Comparing Profiles
131+
132+
The tool generates comparison charts showing memory allocation and peak memory usage before and after optimization. Empirical results highlight reductions in memory usage.
133+
134+
## Results
135+
136+
### Example Outputs
137+
138+
#### Example 1: mem_alloc.cpp
139+
140+
::: {.image-wrapper style="text-align:center;"}
141+
![Example 1: mem_alloc.cpp](fig1.png){ width=100% }
142+
:::
143+
- Total reduction in memory allocation: **37,833.81 KB**
144+
- Reduction in peak memory usage: **788.47 KB**
145+
146+
#### Example 2: mem_fragmentation.cpp
147+
148+
::: {.image-wrapper style="text-align:center;"}
149+
![Example 2: mem_fragmentation.cpp](fig2.png){ width=100% }
150+
:::
151+
- Total reduction in memory allocation: **1,256.08 KB**
152+
- Reduction in peak memory usage: **7.98 KB**
153+
154+
#### Example 3: Cache_miss.cpp
155+
156+
::: {.image-wrapper style="text-align:center;"}
157+
![Example 3: Cache_miss.cpp](fig3.png){ width=100% }
158+
:::
159+
- Total reduction in memory allocation: **2,415.55 KB**
160+
- Reduction in peak memory usage: **397.83 KB**
161+
162+
#### Example 4: growing_ds.cpp
163+
164+
::: {.image-wrapper style="text-align:center;"}
165+
![Example 4: growing_ds.cpp](fig4.png){ width=100% }
166+
:::
167+
- Total reduction in memory allocation: **7,388.50 KB**
168+
- Reduction in peak memory usage: **622.00 KB**
169+
170+
#### Example 5: recursive.cpp
171+
172+
::: {.image-wrapper style="text-align:center;"}
173+
![Example 5: recursive.cpp](fig6.png){ width=100% }
174+
:::
175+
- Total reduction in memory allocation: **43.20 KB**
176+
- Reduction in peak memory usage: **7.20 KB**
177+
178+
## Challenges
179+
180+
### Hardest Parts
181+
182+
1. **Parsing Profiling Data**: Extracting meaningful patterns from Massif's output required converting data into a structured format (CSV).
183+
2. **Code Transformations**: Ensuring that optimizations like replacing `malloc` with `calloc` preserved functionality without introducing bugs.
184+
185+
## Evaluation
186+
187+
The optimizations were successful, with notable reductions in memory allocation and peak usage across all examples. For instance, in `mem_leak.cpp`, the optimized memory allocation dropped by over **2 GB**, showcasing the impact of targeted memory management strategies.
188+
189+
## Conclusion
190+
191+
This project demonstrates that combining Python and ML techniques with traditional profiling tools can effectively optimize memory usage in C++ applications. By automating analysis and applying systematic optimizations, developers can significantly improve efficiency, paving the way for better performance in memory-constrained environments.
192+
193+
194+
195+
This is the code link for this project: https://github.com/gurusamyanandakuma-r/bril/tree/main/HW/Sharmila_Rohit_Project
196+
---

0 commit comments

Comments
 (0)