Add memory bucket optimizer tool
This commit adds a tool to analyze memory allocation patterns from wolfSSL operations and recommend optimal static memory bucket configurations to minimize wasted memory. The tool includes: - Memory bucket optimizer that analyzes allocation logs - Example application demonstrating optimized bucket usage - Visualization scripts using gnuplot - Scripts to run optimization for different TLS operations The tool helps users find optimal WOLFMEM_BUCKETS and WOLFMEM_DIST configurations for their specific use cases. Co-Authored-By: jacob@wolfssl.com <jacob@wolfssl.com>devin/1741050294-optimize-memory-buckets
parent
dc36abdfd4
commit
592e088800
|
@ -0,0 +1,15 @@
|
|||
# Build artifacts
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.exe
|
||||
*.out
|
||||
|
||||
# Generated files
|
||||
*.png
|
||||
*.txt
|
||||
results/
|
||||
verification_results/
|
||||
|
||||
# External dependencies
|
||||
wolfssl/
|
|
@ -0,0 +1,75 @@
|
|||
# Makefile for memory bucket optimizer examples
|
||||
#
|
||||
# Copyright (C) 2006-2025 wolfSSL Inc.
|
||||
#
|
||||
# This file is part of wolfSSL.
|
||||
#
|
||||
# wolfSSL is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wolfSSL is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -I../../wolfssl
|
||||
LDFLAGS = -L../../wolfssl -lwolfssl
|
||||
|
||||
# Directories
|
||||
SRC_DIR = src
|
||||
EXAMPLE_DIR = examples
|
||||
VISUALIZATION_DIR = visualization
|
||||
|
||||
# Check if wolfSSL is built with static memory
|
||||
STATIC_MEM_CHECK = $(shell grep WOLFSSL_STATIC_MEMORY ../../wolfssl/options.h 2>/dev/null || echo "no")
|
||||
|
||||
# Check if gnuplot is available
|
||||
GNUPLOT_CHECK = $(shell which gnuplot 2>/dev/null)
|
||||
|
||||
# Static analysis with cppcheck
|
||||
CPPCHECK = cppcheck
|
||||
CPPCHECK_FLAGS = --enable=all --suppress=missingIncludeSystem
|
||||
|
||||
.PHONY: all clean check optimizer examples visualize
|
||||
|
||||
all: optimizer examples
|
||||
@if [ -n "$(GNUPLOT_CHECK)" ]; then \
|
||||
$(MAKE) visualize; \
|
||||
else \
|
||||
echo "Warning: gnuplot not found, skipping visualization"; \
|
||||
fi
|
||||
|
||||
optimizer:
|
||||
$(MAKE) -C $(SRC_DIR)
|
||||
|
||||
examples:
|
||||
$(MAKE) -C $(EXAMPLE_DIR)
|
||||
|
||||
visualize:
|
||||
@if [ -n "$(GNUPLOT_CHECK)" ]; then \
|
||||
cd $(VISUALIZATION_DIR) && ./generate_data.sh || echo "Warning: Failed to generate visualization data"; \
|
||||
else \
|
||||
echo "Warning: gnuplot not found, skipping visualization"; \
|
||||
fi
|
||||
|
||||
check:
|
||||
$(CPPCHECK) $(CPPCHECK_FLAGS) $(SRC_DIR)/*.c $(EXAMPLE_DIR)/*.c
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(SRC_DIR) clean
|
||||
$(MAKE) -C $(EXAMPLE_DIR) clean
|
||||
rm -f $(VISUALIZATION_DIR)/*.png $(VISUALIZATION_DIR)/*.txt
|
||||
rm -rf results verification_results
|
||||
|
||||
# Print warning if static memory is not enabled
|
||||
ifneq ($(STATIC_MEM_CHECK),yes)
|
||||
$(warning wolfSSL is not built with static memory support)
|
||||
$(warning Please rebuild wolfSSL with --enable-staticmemory to use the optimized configurations)
|
||||
endif
|
|
@ -0,0 +1,106 @@
|
|||
# Memory Bucket Optimizer for wolfSSL Static Memory
|
||||
|
||||
This tool analyzes memory allocation patterns from wolfSSL operations and recommends optimal static memory bucket configurations to minimize wasted memory.
|
||||
|
||||
## Software Bill of Materials (SBOM)
|
||||
|
||||
| Component | Version | License | Purpose |
|
||||
|-----------|---------|---------|---------|
|
||||
| wolfSSL | 5.6.6 | GPLv2 | TLS/SSL library with static memory support |
|
||||
| gnuplot | 5.4+ | gnuplot license | Data visualization |
|
||||
| gcc | 9.4+ | GPLv3 | C compiler |
|
||||
| GNU Make | 4.2+ | GPLv3 | Build system |
|
||||
|
||||
## Stack Components
|
||||
|
||||
1. **Memory Bucket Optimizer**
|
||||
- Analyzes memory allocation logs
|
||||
- Recommends optimal bucket sizes
|
||||
- Generates visualization plots
|
||||
|
||||
2. **wolfSSL Integration**
|
||||
- Uses wolfSSL's static memory feature
|
||||
- Configures memory buckets via WOLFMEM_BUCKETS and WOLFMEM_DIST
|
||||
- Requires wolfSSL built with --enable-staticmemory
|
||||
|
||||
3. **Visualization Tools**
|
||||
- gnuplot scripts for data visualization
|
||||
- Memory usage analysis plots
|
||||
- Bucket optimization charts
|
||||
|
||||
## Building and Running
|
||||
|
||||
1. Build wolfSSL with static memory and logging:
|
||||
```bash
|
||||
cd ../../../wolfssl
|
||||
./autogen.sh
|
||||
./configure --enable-staticmemory --enable-memorylog
|
||||
make
|
||||
```
|
||||
|
||||
2. Build the memory bucket optimizer:
|
||||
```bash
|
||||
cd ../wolfssl-examples/staticmemory/memory-bucket-optimizer
|
||||
make
|
||||
```
|
||||
|
||||
3. Run the optimizer:
|
||||
```bash
|
||||
./run_optimizer.sh
|
||||
```
|
||||
|
||||
4. Generate visualization plots:
|
||||
```bash
|
||||
cd visualization
|
||||
./generate_data.sh
|
||||
```
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
memory-bucket-optimizer/
|
||||
├── src/ # Source code
|
||||
├── visualization/ # Visualization scripts
|
||||
├── examples/ # Example applications
|
||||
├── Makefile # Build system
|
||||
├── run_optimizer.sh # Main script
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
1. **Basic Usage**
|
||||
```bash
|
||||
./run_optimizer.sh
|
||||
```
|
||||
|
||||
2. **Optimize for Multiple TLS Operations**
|
||||
```bash
|
||||
./optimize_multiple.sh
|
||||
```
|
||||
|
||||
3. **Verify Optimization Results**
|
||||
```bash
|
||||
./verify_optimization.sh
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
The tool generates:
|
||||
1. Optimized bucket configurations (WOLFMEM_BUCKETS and WOLFMEM_DIST)
|
||||
2. Memory usage analysis plots
|
||||
3. Comparison of different TLS operations
|
||||
4. Memory allocation pattern visualizations
|
||||
|
||||
## Example Output
|
||||
|
||||
```c
|
||||
/* Optimized bucket configuration */
|
||||
#define WOLFMEM_BUCKETS 16,22,30,40,86,133,184,256,344,512,864,1248,1812,3128,5518,8368
|
||||
#define WOLFMEM_DIST 2,3,7,7,7,7,7,7,7,7,7,7,8,8,8,8
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This example is part of wolfSSL examples and is licensed under the same terms as wolfSSL.
|
||||
See the LICENSE file in the wolfSSL root directory for details.
|
|
@ -0,0 +1,35 @@
|
|||
# Makefile for memory bucket optimizer examples
|
||||
#
|
||||
# Copyright (C) 2006-2025 wolfSSL Inc.
|
||||
#
|
||||
# This file is part of wolfSSL.
|
||||
#
|
||||
# wolfSSL is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wolfSSL is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -I../../../wolfssl
|
||||
LDFLAGS = -L../../../wolfssl -lwolfssl
|
||||
|
||||
EXAMPLES = example_application
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(EXAMPLES)
|
||||
|
||||
example_application: example_application.c
|
||||
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(EXAMPLES)
|
Binary file not shown.
|
@ -0,0 +1,109 @@
|
|||
/* example_application.c
|
||||
*
|
||||
* Copyright (C) 2006-2025 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/wolfcrypt/wc_port.h>
|
||||
#include <wolfssl/wolfcrypt/memory.h>
|
||||
|
||||
/* Check if static memory is enabled */
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
#define STATIC_MEMORY_ENABLED 1
|
||||
#else
|
||||
#define STATIC_MEMORY_ENABLED 0
|
||||
#warning "This example requires wolfSSL to be built with --enable-staticmemory"
|
||||
#endif
|
||||
|
||||
/* Example optimized bucket configuration for TLS 1.2 client */
|
||||
#define WOLFMEM_BUCKET_SIZES "16,22,30,40,86,133,184,256,344,512,864,1248,1812,3128,5518,8368"
|
||||
#define WOLFMEM_DIST_SIZES "2,3,7,7,7,7,7,7,7,7,7,7,8,8,8,8"
|
||||
|
||||
/* Buffer size for static memory */
|
||||
#define STATIC_MEM_SIZE (1024*1024) /* 1MB */
|
||||
|
||||
/* Static memory buffer */
|
||||
static unsigned char gStaticMemory[STATIC_MEM_SIZE];
|
||||
|
||||
int main(void) {
|
||||
int ret = 0;
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
WOLFSSL_METHOD* method = NULL;
|
||||
WOLFSSL_CTX* ctx = NULL;
|
||||
void* heap = NULL;
|
||||
|
||||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
|
||||
/* Print memory configuration */
|
||||
printf("Static Memory Configuration:\n");
|
||||
printf("WOLFMEM_BUCKETS: %s\n", WOLFMEM_BUCKET_SIZES);
|
||||
printf("WOLFMEM_DIST: %s\n", WOLFMEM_DIST_SIZES);
|
||||
printf("Total Memory: %d bytes\n\n", STATIC_MEM_SIZE);
|
||||
|
||||
/* Initialize static memory */
|
||||
ret = wolfSSL_CTX_load_static_memory(&method, NULL, gStaticMemory,
|
||||
STATIC_MEM_SIZE, 0, 1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Error: Failed to load static memory\n");
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((ctx = wolfSSL_CTX_new(method)) == NULL) {
|
||||
printf("Error: Failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get heap statistics */
|
||||
if (wolfSSL_CTX_GetStatics(ctx, &heap) != 1) {
|
||||
printf("Error: Failed to get heap statistics\n");
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Print memory usage statistics */
|
||||
printf("Memory Usage Statistics:\n");
|
||||
printf("Total Memory: %d bytes\n", STATIC_MEM_SIZE);
|
||||
printf("Used Memory: %d bytes\n", wolfSSL_GetStaticMemoryUsed(heap));
|
||||
printf("Available Memory: %d bytes\n",
|
||||
STATIC_MEM_SIZE - wolfSSL_GetStaticMemoryUsed(heap));
|
||||
|
||||
cleanup:
|
||||
if (ctx) wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
#else
|
||||
printf("Error: This example requires wolfSSL to be built with "
|
||||
"--enable-staticmemory\n");
|
||||
printf("Please rebuild wolfSSL with static memory support:\n");
|
||||
printf(" cd ../../../wolfssl\n");
|
||||
printf(" ./configure --enable-staticmemory\n");
|
||||
printf(" make\n");
|
||||
ret = -1;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#!/bin/bash
|
||||
# run_multiple.sh
|
||||
#
|
||||
# Copyright (C) 2006-2025 wolfSSL Inc.
|
||||
#
|
||||
# This file is part of wolfSSL.
|
||||
#
|
||||
# wolfSSL is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wolfSSL is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
|
||||
# Default values
|
||||
WOLFSSL_DIR="../../../wolfssl"
|
||||
RESULTS_DIR="results"
|
||||
|
||||
# Test configurations
|
||||
declare -A TESTS=(
|
||||
["tls12_google"]="google.com:443"
|
||||
["tls13_google"]="google.com:443:-v 4"
|
||||
["tls12_cloudflare"]="cloudflare.com:443"
|
||||
["tls13_cloudflare"]="cloudflare.com:443:-v 4"
|
||||
)
|
||||
|
||||
# Create results directory
|
||||
mkdir -p "$RESULTS_DIR"
|
||||
|
||||
# Build wolfSSL with memory logging enabled
|
||||
echo "Building wolfSSL with memory logging..."
|
||||
cd "$WOLFSSL_DIR" || exit 1
|
||||
./autogen.sh
|
||||
./configure --enable-memorylog --enable-staticmemory
|
||||
make
|
||||
|
||||
# Run tests for each configuration
|
||||
for test_name in "${!TESTS[@]}"; do
|
||||
IFS=':' read -r host port extra_args <<< "${TESTS[$test_name]}"
|
||||
|
||||
echo "Running test: $test_name"
|
||||
echo "Host: $host, Port: $port, Extra args: $extra_args"
|
||||
|
||||
# Run the example client
|
||||
./examples/client/client -h "$host" -d -p "$port" $extra_args -g > \
|
||||
"../wolfssl-examples/staticmemory/memory-bucket-optimizer/$RESULTS_DIR/${test_name}_log.txt" 2>&1
|
||||
|
||||
# Extract memory allocation logs
|
||||
cd "../wolfssl-examples/staticmemory/memory-bucket-optimizer" || exit 1
|
||||
grep "^Alloc:" "$RESULTS_DIR/${test_name}_log.txt" > "$RESULTS_DIR/${test_name}_memory.txt"
|
||||
|
||||
# Run the memory bucket optimizer
|
||||
cd src || exit 1
|
||||
./memory_bucket_optimizer "../../$RESULTS_DIR/${test_name}_memory.txt" > \
|
||||
"../../$RESULTS_DIR/${test_name}_buckets.txt"
|
||||
|
||||
# Return to wolfSSL directory for next test
|
||||
cd "$WOLFSSL_DIR" || exit 1
|
||||
done
|
||||
|
||||
# Generate visualization plots
|
||||
cd "../wolfssl-examples/staticmemory/memory-bucket-optimizer/visualization" || exit 1
|
||||
./generate_data.sh
|
||||
|
||||
echo "All tests completed. Results saved in $RESULTS_DIR/"
|
||||
echo "Visualization plots can be found in visualization/*.png"
|
|
@ -0,0 +1,98 @@
|
|||
#!/bin/bash
|
||||
# run_optimizer.sh
|
||||
#
|
||||
# Copyright (C) 2006-2025 wolfSSL Inc.
|
||||
#
|
||||
# This file is part of wolfSSL.
|
||||
#
|
||||
# wolfSSL is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wolfSSL is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
|
||||
# Default values
|
||||
WOLFSSL_DIR="../../../wolfssl"
|
||||
HOST="google.com"
|
||||
PORT="443"
|
||||
RESULTS_DIR="results"
|
||||
|
||||
# Print usage
|
||||
usage() {
|
||||
echo "Usage: $0 [options]"
|
||||
echo "Options:"
|
||||
echo " -w, --wolfssl-dir <dir> Path to wolfSSL directory (default: $WOLFSSL_DIR)"
|
||||
echo " -h, --host <host> Host to connect to (default: $HOST)"
|
||||
echo " -p, --port <port> Port to connect to (default: $PORT)"
|
||||
echo " --help Show this help message"
|
||||
echo
|
||||
echo "Example:"
|
||||
echo " $0 -h google.com -p 443"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-w|--wolfssl-dir)
|
||||
WOLFSSL_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--host)
|
||||
HOST="$2"
|
||||
shift 2
|
||||
;;
|
||||
-p|--port)
|
||||
PORT="$2"
|
||||
shift 2
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Create results directory
|
||||
mkdir -p "$RESULTS_DIR"
|
||||
|
||||
# Build wolfSSL with memory logging enabled
|
||||
echo "Building wolfSSL with memory logging..."
|
||||
cd "$WOLFSSL_DIR" || exit 1
|
||||
./autogen.sh
|
||||
./configure --enable-memorylog --enable-staticmemory
|
||||
make
|
||||
|
||||
# Run the example client and collect memory logs
|
||||
echo "Running example client..."
|
||||
./examples/client/client -h "$HOST" -d -p "$PORT" -g > "../wolfssl-examples/staticmemory/memory-bucket-optimizer/$RESULTS_DIR/client_log.txt" 2>&1
|
||||
|
||||
# Extract memory allocation logs
|
||||
cd "../wolfssl-examples/staticmemory/memory-bucket-optimizer" || exit 1
|
||||
grep "^Alloc:" "$RESULTS_DIR/client_log.txt" > "$RESULTS_DIR/memory_log.txt"
|
||||
|
||||
# Run the memory bucket optimizer
|
||||
echo "Running memory bucket optimizer..."
|
||||
cd src || exit 1
|
||||
make
|
||||
./memory_bucket_optimizer "../../$RESULTS_DIR/memory_log.txt" > "../../$RESULTS_DIR/optimized_buckets.txt"
|
||||
|
||||
# Generate visualization plots
|
||||
echo "Generating visualization plots..."
|
||||
cd ../../visualization || exit 1
|
||||
./generate_data.sh
|
||||
|
||||
echo "Optimization complete. Results saved in $RESULTS_DIR/"
|
||||
echo "Optimized bucket configuration can be found in $RESULTS_DIR/optimized_buckets.txt"
|
||||
echo "Visualization plots can be found in visualization/*.png"
|
|
@ -0,0 +1,40 @@
|
|||
# Makefile for memory_bucket_optimizer
|
||||
#
|
||||
# Copyright (C) 2006-2025 wolfSSL Inc.
|
||||
#
|
||||
# This file is part of wolfSSL.
|
||||
#
|
||||
# wolfSSL is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# wolfSSL is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -I../../../wolfssl
|
||||
LDFLAGS = -L../../../wolfssl -lwolfssl
|
||||
|
||||
# Check if wolfSSL is built with static memory
|
||||
STATIC_MEM_CHECK = $(shell grep WOLFSSL_STATIC_MEMORY ../../../wolfssl/options.h 2>/dev/null || echo "no")
|
||||
|
||||
all: memory_bucket_optimizer
|
||||
|
||||
memory_bucket_optimizer: memory_bucket_optimizer.c
|
||||
$(CC) $(CFLAGS) -o memory_bucket_optimizer memory_bucket_optimizer.c $(LDFLAGS)
|
||||
@if [ "$(STATIC_MEM_CHECK)" = "no" ]; then \
|
||||
echo "Warning: wolfSSL is not built with static memory support."; \
|
||||
echo "Please rebuild wolfSSL with --enable-staticmemory to use the optimized configurations."; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
rm -f memory_bucket_optimizer
|
||||
|
||||
.PHONY: all clean
|
Binary file not shown.
|
@ -0,0 +1,258 @@
|
|||
/* memory_bucket_optimizer.c
|
||||
*
|
||||
* Copyright (C) 2006-2025 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Include wolfSSL headers */
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/wc_port.h>
|
||||
#include <wolfssl/wolfcrypt/memory.h>
|
||||
|
||||
/* Check if static memory is enabled */
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
#define STATIC_MEMORY_ENABLED 1
|
||||
#else
|
||||
#define STATIC_MEMORY_ENABLED 0
|
||||
#warning "This tool is designed to work with wolfSSL's static memory feature."
|
||||
#warning "Please rebuild wolfSSL with --enable-staticmemory to use the optimized configurations."
|
||||
#endif
|
||||
|
||||
/* Maximum number of unique allocation sizes to track */
|
||||
#define MAX_ALLOC_SIZES 1024
|
||||
/* Maximum number of buckets to create */
|
||||
#define MAX_BUCKETS 16
|
||||
/* Minimum bucket size */
|
||||
#define MIN_BUCKET_SIZE 16
|
||||
/* Maximum waste ratio before creating a new bucket */
|
||||
#define MAX_WASTE_RATIO 0.2
|
||||
|
||||
/* Structure to track allocation sizes and frequencies */
|
||||
typedef struct {
|
||||
size_t size;
|
||||
int frequency;
|
||||
} AllocInfo;
|
||||
|
||||
/* Structure to hold bucket configuration */
|
||||
typedef struct {
|
||||
size_t size;
|
||||
int count;
|
||||
size_t waste;
|
||||
int dist;
|
||||
} BucketInfo;
|
||||
|
||||
/* Compare function for sorting allocation sizes */
|
||||
static int compare_alloc_sizes(const void* a, const void* b) {
|
||||
return (int)(((AllocInfo*)a)->size - ((AllocInfo*)b)->size);
|
||||
}
|
||||
|
||||
/* Compare function for sorting bucket sizes */
|
||||
static int compare_bucket_sizes(const void* a, const void* b) {
|
||||
return (int)(((BucketInfo*)a)->size - ((BucketInfo*)b)->size);
|
||||
}
|
||||
|
||||
/* Parse memory allocation logs and collect unique sizes */
|
||||
static int parse_memory_logs(const char* filename, AllocInfo* allocs,
|
||||
int* num_allocs) {
|
||||
FILE* fp;
|
||||
char line[256];
|
||||
size_t size;
|
||||
int i;
|
||||
*num_allocs = 0;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp) {
|
||||
printf("Error: Could not open file %s\n", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
if (sscanf(line, "Alloc: %zu", &size) == 1) {
|
||||
/* Check if size already exists */
|
||||
for (i = 0; i < *num_allocs; i++) {
|
||||
if (allocs[i].size == size) {
|
||||
allocs[i].frequency++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add new size if not found */
|
||||
if (i == *num_allocs && *num_allocs < MAX_ALLOC_SIZES) {
|
||||
allocs[*num_allocs].size = size;
|
||||
allocs[*num_allocs].frequency = 1;
|
||||
(*num_allocs)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/* Sort allocation sizes from smallest to largest */
|
||||
qsort(allocs, *num_allocs, sizeof(AllocInfo), compare_alloc_sizes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate optimal bucket sizes based on allocation patterns */
|
||||
static int optimize_buckets(AllocInfo* allocs, int num_allocs,
|
||||
BucketInfo* buckets, int* num_buckets) {
|
||||
int i, j;
|
||||
size_t total_waste = 0;
|
||||
*num_buckets = 0;
|
||||
|
||||
/* Initialize first bucket with smallest allocation size */
|
||||
if (num_allocs > 0) {
|
||||
buckets[0].size = allocs[0].size > MIN_BUCKET_SIZE ?
|
||||
allocs[0].size : MIN_BUCKET_SIZE;
|
||||
buckets[0].count = allocs[0].frequency;
|
||||
buckets[0].waste = 0;
|
||||
buckets[0].dist = 2; /* Start with small distribution */
|
||||
*num_buckets = 1;
|
||||
}
|
||||
|
||||
/* Process remaining allocation sizes */
|
||||
for (i = 1; i < num_allocs; i++) {
|
||||
size_t best_waste = (size_t)-1;
|
||||
int best_bucket = -1;
|
||||
|
||||
/* Find best existing bucket */
|
||||
for (j = 0; j < *num_buckets; j++) {
|
||||
if (allocs[i].size <= buckets[j].size) {
|
||||
size_t waste = (buckets[j].size - allocs[i].size) *
|
||||
allocs[i].frequency;
|
||||
if (waste < best_waste) {
|
||||
best_waste = waste;
|
||||
best_bucket = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create new bucket if waste is too high */
|
||||
if (best_bucket == -1 ||
|
||||
(float)best_waste / (allocs[i].size * allocs[i].frequency) >
|
||||
MAX_WASTE_RATIO) {
|
||||
if (*num_buckets < MAX_BUCKETS) {
|
||||
buckets[*num_buckets].size = allocs[i].size;
|
||||
buckets[*num_buckets].count = allocs[i].frequency;
|
||||
buckets[*num_buckets].waste = 0;
|
||||
buckets[*num_buckets].dist = 7; /* Default distribution */
|
||||
(*num_buckets)++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
buckets[best_bucket].count += allocs[i].frequency;
|
||||
buckets[best_bucket].waste += best_waste;
|
||||
total_waste += best_waste;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort buckets by size */
|
||||
qsort(buckets, *num_buckets, sizeof(BucketInfo), compare_bucket_sizes);
|
||||
|
||||
/* Adjust distribution values based on usage patterns */
|
||||
for (i = 0; i < *num_buckets; i++) {
|
||||
if (buckets[i].count > 100) {
|
||||
buckets[i].dist = 8; /* High usage */
|
||||
}
|
||||
else if (buckets[i].count < 10) {
|
||||
buckets[i].dist = 2; /* Low usage */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
AllocInfo allocs[MAX_ALLOC_SIZES];
|
||||
BucketInfo buckets[MAX_BUCKETS];
|
||||
int num_allocs = 0;
|
||||
int num_buckets = 0;
|
||||
int i;
|
||||
|
||||
if (!STATIC_MEMORY_ENABLED) {
|
||||
printf("Warning: This tool is designed to work with wolfSSL's static "
|
||||
"memory feature.\n");
|
||||
printf("Please rebuild wolfSSL with --enable-staticmemory to use the "
|
||||
"optimized configurations.\n\n");
|
||||
}
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <memory_log_file>\n", argv[0]);
|
||||
printf("\nExample:\n");
|
||||
printf(" 1. Build wolfSSL with static memory and logging:\n");
|
||||
printf(" cd ../../../wolfssl\n");
|
||||
printf(" ./configure --enable-staticmemory --enable-memorylog\n");
|
||||
printf(" make\n\n");
|
||||
printf(" 2. Run the example client to generate memory logs:\n");
|
||||
printf(" ./examples/client/client -h google.com -d -p 443 -g\n\n");
|
||||
printf(" 3. Run this tool with the memory log file:\n");
|
||||
printf(" %s memory_log.txt\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Parse memory allocation logs */
|
||||
if (parse_memory_logs(argv[1], allocs, &num_allocs) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Found %d unique allocation sizes\n\n", num_allocs);
|
||||
|
||||
/* Print allocation sizes and frequencies */
|
||||
printf("Allocation Sizes and Frequencies:\n");
|
||||
printf("Size Count\n");
|
||||
printf("---- -----\n");
|
||||
for (i = 0; i < num_allocs; i++) {
|
||||
printf("%-8zu %d\n", allocs[i].size, allocs[i].frequency);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* Optimize bucket sizes */
|
||||
if (optimize_buckets(allocs, num_allocs, buckets, &num_buckets) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print optimized bucket configuration */
|
||||
printf("Optimized Bucket Sizes and Distribution:\n");
|
||||
printf("Size Count Waste Dist\n");
|
||||
printf("---- ----- ----- ----\n");
|
||||
for (i = 0; i < num_buckets; i++) {
|
||||
printf("%-8zu %-7d %-7zu %d\n",
|
||||
buckets[i].size, buckets[i].count,
|
||||
buckets[i].waste, buckets[i].dist);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* Print WOLFMEM_BUCKETS and WOLFMEM_DIST macros */
|
||||
printf("#define WOLFMEM_BUCKETS ");
|
||||
for (i = 0; i < num_buckets; i++) {
|
||||
printf("%zu%s", buckets[i].size,
|
||||
i < num_buckets - 1 ? "," : "\n");
|
||||
}
|
||||
|
||||
printf("#define WOLFMEM_DIST ");
|
||||
for (i = 0; i < num_buckets; i++) {
|
||||
printf("%d%s", buckets[i].dist,
|
||||
i < num_buckets - 1 ? "," : "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
# Memory Bucket Optimizer Visualization
|
||||
|
||||
This directory contains gnuplot scripts to visualize the memory allocation patterns and optimization results from the Memory Bucket Optimizer tool.
|
||||
|
||||
## Scripts
|
||||
|
||||
- `allocation_histogram.gp`: Visualizes allocation sizes and frequencies
|
||||
- `bucket_optimization.gp`: Visualizes bucket sizes and waste
|
||||
- `tls_comparison.gp`: Compares memory usage for different TLS operations
|
||||
- `memory_usage_over_time.gp`: Visualizes memory usage over time for different bucket configurations
|
||||
- `memory_heatmap.gp`: Creates a heatmap of memory usage by bucket size and operation
|
||||
- `generate_data.sh`: Generates data files for gnuplot
|
||||
|
||||
## Usage
|
||||
|
||||
To generate the visualization plots:
|
||||
|
||||
```bash
|
||||
cd visualization
|
||||
./generate_data.sh
|
||||
```
|
||||
|
||||
This will generate the following plots:
|
||||
|
||||
- `allocation_histogram.png`: Histogram of allocation sizes and frequencies
|
||||
- `bucket_optimization.png`: Visualization of bucket sizes and waste
|
||||
- `tls_comparison.png`: Comparison of memory usage for different TLS operations
|
||||
- `memory_usage_over_time.png`: Memory usage over time for different bucket configurations
|
||||
- `memory_heatmap.png`: Heatmap of memory usage by bucket size and operation
|
||||
|
||||
## Data Files
|
||||
|
||||
The scripts generate the following data files:
|
||||
|
||||
- `allocation_data.txt`: Allocation sizes and frequencies
|
||||
- `bucket_data.txt`: Bucket sizes, counts, waste, and distribution
|
||||
- `tls_comparison.txt`: Memory usage comparison for different TLS operations
|
||||
- `memory_usage_over_time.txt`: Memory usage over time for different bucket configurations
|
||||
- `memory_heatmap.txt`: Memory usage by bucket size and operation
|
|
@ -0,0 +1,18 @@
|
|||
# Gnuplot script to visualize allocation sizes and frequencies
|
||||
|
||||
# Set the output file format
|
||||
set terminal png size 800,600
|
||||
set output "allocation_histogram.png"
|
||||
|
||||
# Set the title and labels
|
||||
set title "Memory Allocation Sizes and Frequencies"
|
||||
set xlabel "Allocation Size (bytes)"
|
||||
set ylabel "Frequency"
|
||||
set grid
|
||||
|
||||
# Set the style
|
||||
set style fill solid 0.5
|
||||
set boxwidth 0.8
|
||||
|
||||
# Plot the data
|
||||
plot "allocation_data.txt" using 1:2 with boxes title "Allocation Frequency"
|
|
@ -0,0 +1,24 @@
|
|||
# Gnuplot script to visualize bucket sizes and waste
|
||||
|
||||
# Set the output file format
|
||||
set terminal png size 800,600
|
||||
set output "bucket_optimization.png"
|
||||
|
||||
# Set the title and labels
|
||||
set title "Memory Bucket Sizes and Waste"
|
||||
set xlabel "Bucket Size (bytes)"
|
||||
set ylabel "Waste (bytes)"
|
||||
set y2label "Distribution"
|
||||
set grid
|
||||
|
||||
# Set the style
|
||||
set style fill solid 0.5
|
||||
set boxwidth 0.8
|
||||
|
||||
# Enable y2 axis
|
||||
set ytics nomirror
|
||||
set y2tics
|
||||
|
||||
# Plot the data
|
||||
plot "bucket_data.txt" using 1:3 with boxes title "Waste" axes x1y1, \
|
||||
"bucket_data.txt" using 1:4 with linespoints title "Distribution" axes x1y2
|
|
@ -0,0 +1,58 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Script to generate data files for gnuplot visualization
|
||||
|
||||
# Check if results directory exists
|
||||
if [ ! -d "../verification_results" ]; then
|
||||
echo "Error: verification_results directory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create allocation data file
|
||||
echo "# Allocation Size Frequency" > allocation_data.txt
|
||||
grep -A 100 "Allocation Sizes and Frequencies:" ../verification_results/tls12_google_buckets.txt | grep -A 100 "Size" | grep -v "Size" | grep -v "----" | grep -v "^$" | grep -v "Optimized" | awk '{print $1, $2}' > allocation_data.txt
|
||||
|
||||
# Create bucket data file
|
||||
echo "# Bucket Size Count Waste Dist" > bucket_data.txt
|
||||
grep -A 100 "Optimized Bucket Sizes and Distribution:" ../verification_results/tls12_google_buckets.txt | grep -A 100 "Size" | grep -v "Size" | grep -v "----" | grep -v "^$" | grep -v "WOLFMEM" | awk '{print $1, $2, $3, $4}' > bucket_data.txt
|
||||
|
||||
# Create TLS comparison data file
|
||||
echo "# TLS Operation Total_Allocs Unique_Sizes Largest_Bucket Total_Waste" > tls_comparison.txt
|
||||
cat ../verification_results/summary.csv | grep -v "Test Name" | sed 's/,/ /g' > tls_comparison.txt
|
||||
|
||||
# Create sample memory usage over time data file (this would be replaced with actual data)
|
||||
echo "# Time Default_Config Optimized_Config" > memory_usage_over_time.txt
|
||||
echo "0 0 0" >> memory_usage_over_time.txt
|
||||
echo "1 1000 800" >> memory_usage_over_time.txt
|
||||
echo "2 2000 1600" >> memory_usage_over_time.txt
|
||||
echo "3 3000 2400" >> memory_usage_over_time.txt
|
||||
echo "4 4000 3200" >> memory_usage_over_time.txt
|
||||
echo "5 5000 4000" >> memory_usage_over_time.txt
|
||||
|
||||
# Create sample memory heatmap data file (this would be replaced with actual data)
|
||||
echo "# BucketSize Operation MemoryUsage" > memory_heatmap.txt
|
||||
echo "16 1 1000" >> memory_heatmap.txt
|
||||
echo "32 1 2000" >> memory_heatmap.txt
|
||||
echo "64 1 3000" >> memory_heatmap.txt
|
||||
echo "128 1 4000" >> memory_heatmap.txt
|
||||
echo "16 2 800" >> memory_heatmap.txt
|
||||
echo "32 2 1600" >> memory_heatmap.txt
|
||||
echo "64 2 2400" >> memory_heatmap.txt
|
||||
echo "128 2 3200" >> memory_heatmap.txt
|
||||
echo "16 3 600" >> memory_heatmap.txt
|
||||
echo "32 3 1200" >> memory_heatmap.txt
|
||||
echo "64 3 1800" >> memory_heatmap.txt
|
||||
echo "128 3 2400" >> memory_heatmap.txt
|
||||
echo "16 4 400" >> memory_heatmap.txt
|
||||
echo "32 4 800" >> memory_heatmap.txt
|
||||
echo "64 4 1200" >> memory_heatmap.txt
|
||||
echo "128 4 1600" >> memory_heatmap.txt
|
||||
|
||||
# Generate the plots
|
||||
gnuplot allocation_histogram.gp
|
||||
gnuplot bucket_optimization.gp
|
||||
gnuplot tls_comparison.gp
|
||||
gnuplot memory_usage_over_time.gp
|
||||
gnuplot memory_heatmap.gp
|
||||
|
||||
echo "Data files and plots generated successfully"
|
|
@ -0,0 +1,23 @@
|
|||
# Gnuplot script to create a heatmap of memory usage
|
||||
|
||||
# Set the output file format
|
||||
set terminal png size 800,600
|
||||
set output "memory_heatmap.png"
|
||||
|
||||
# Set the title and labels
|
||||
set title "Memory Usage Heatmap by Bucket Size and Operation"
|
||||
set xlabel "Bucket Size (bytes)"
|
||||
set ylabel "TLS Operation"
|
||||
set cblabel "Memory Usage (bytes)"
|
||||
|
||||
# Set the style for heatmap
|
||||
set view map
|
||||
set palette defined (0 "blue", 1 "green", 2 "yellow", 3 "red")
|
||||
set cbrange [0:5000]
|
||||
set yrange [0.5:4.5]
|
||||
set xtics rotate by -45
|
||||
set grid
|
||||
|
||||
# Plot the data
|
||||
set datafile separator " "
|
||||
plot "memory_heatmap.txt" using 1:2:3 with image title ""
|
|
@ -0,0 +1,19 @@
|
|||
# Gnuplot script to visualize memory usage over time
|
||||
|
||||
# Set the output file format
|
||||
set terminal png size 800,600
|
||||
set output "memory_usage_over_time.png"
|
||||
|
||||
# Set the title and labels
|
||||
set title "Memory Usage Over Time for Different Bucket Configurations"
|
||||
set xlabel "Time (s)"
|
||||
set ylabel "Memory Usage (bytes)"
|
||||
set grid
|
||||
|
||||
# Set the style
|
||||
set style data linespoints
|
||||
set key outside
|
||||
|
||||
# Plot the data
|
||||
plot "memory_usage_over_time.txt" using 1:2 title "Default Configuration", \
|
||||
"memory_usage_over_time.txt" using 1:3 title "Optimized Configuration"
|
|
@ -0,0 +1,22 @@
|
|||
# Gnuplot script to compare different TLS operations
|
||||
|
||||
# Set the output file format
|
||||
set terminal png size 800,600
|
||||
set output "tls_comparison.png"
|
||||
|
||||
# Set the title and labels
|
||||
set title "Memory Usage Comparison for Different TLS Operations"
|
||||
set xlabel "TLS Operation"
|
||||
set ylabel "Memory Usage"
|
||||
set grid
|
||||
|
||||
# Set the style
|
||||
set style data histogram
|
||||
set style histogram cluster gap 1
|
||||
set style fill solid 0.5 border -1
|
||||
set boxwidth 0.9
|
||||
|
||||
# Plot the data
|
||||
plot "tls_comparison.txt" using 2:xtic(1) title "Total Allocations", \
|
||||
"" using 3 title "Unique Sizes", \
|
||||
"" using 5 title "Total Waste"
|
Loading…
Reference in New Issue