Skip to content

Commit 9a57a68

Browse files
(Perf improvement) Keep dynamically allocated memory in filterPeaks().
Allocating and freeing memory added an extra ~10% time in the example model included for testing. So, now it allocates on first use or if it needs a larger buffers. It never deallocates, but the memory consumption penalty is worth the runtime performance improvement, as we expect the model to be constantly running in the bacground.
1 parent c220651 commit 9a57a68

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

mlrunner/mldataprocessor.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,28 @@ MldpReturn_t filterPeaks(const float *data_in, const int in_size, float *data_ou
9090
return MLDP_ERROR_CONFIG;
9191
}
9292

93-
// micro:bit allocator panics if there is not enough memory, no need to check
94-
float *signals = (float *)malloc(in_size * sizeof(float));
95-
float *filtered_y = (float *)malloc(in_size * sizeof(float));
96-
float *avg_filter = (float *)malloc(in_size * sizeof(float));
97-
float *std_filter = (float *)malloc(in_size * sizeof(float));
93+
static float *signals = NULL;
94+
static float *filtered_y = NULL;
95+
static float *avg_filter = NULL;
96+
static float *std_filter = NULL;
97+
static int arrays_alloc_size = 0;
9898
float lead_in[lag];
9999

100+
// Keep memory allocated between calls to avoid malloc/free overhead
101+
if (arrays_alloc_size < in_size) {
102+
free(signals); free(filtered_y); free(avg_filter); free(std_filter);
103+
signals = (float *)malloc(in_size * sizeof(float));
104+
filtered_y = (float *)malloc(in_size * sizeof(float));
105+
avg_filter = (float *)malloc(in_size * sizeof(float));
106+
std_filter = (float *)malloc(in_size * sizeof(float));
107+
if (signals == NULL || filtered_y == NULL || avg_filter == NULL|| std_filter == NULL) {
108+
free(signals); free(filtered_y); free(avg_filter); free(std_filter);
109+
signals = NULL; filtered_y = NULL; avg_filter = NULL; std_filter = NULL;
110+
arrays_alloc_size = 0;
111+
return MLDP_ERROR_ALLOC;
112+
}
113+
arrays_alloc_size = in_size;
114+
}
100115
memset(signals, 0, in_size * sizeof(float));
101116
memcpy(filtered_y, data_in, lag * sizeof(float));
102117
memcpy(lead_in, data_in, lag * sizeof(float));
@@ -113,8 +128,10 @@ MldpReturn_t filterPeaks(const float *data_in, const int in_size, float *data_ou
113128

114129
int peaksCounter = 0;
115130
for (int i = lag; i < in_size; i++) {
116-
if (fabsf(data_in[i] - avg_filter[i - 1]) > 0.1f &&
117-
fabsf(data_in[i] - avg_filter[i - 1]) > threshold * std_filter[i - 1]
131+
const float diff = fabsf(data_in[i] - avg_filter[i - 1]);
132+
if (
133+
diff > 0.1f &&
134+
diff > threshold * std_filter[i - 1]
118135
) {
119136
if (data_in[i] > avg_filter[i - 1]) {
120137
signals[i] = +1; // positive signal
@@ -141,11 +158,6 @@ MldpReturn_t filterPeaks(const float *data_in, const int in_size, float *data_ou
141158
}
142159
*data_out = peaksCounter;
143160

144-
free(signals);
145-
free(filtered_y);
146-
free(avg_filter);
147-
free(std_filter);
148-
149161
return MLDP_SUCCESS;
150162
}
151163

0 commit comments

Comments
 (0)