Skip to content

Commit 215636e

Browse files
committed
Tools: Testbench: Track and print heap usage for modules
This patch adds to end to sof-testbench4 run print of peak heap consumption for each module. The information is retrieved from heap_high_water_mark data that is tracked by module adapter for each module. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent f3c2e7e commit 215636e

File tree

2 files changed

+64
-9
lines changed

2 files changed

+64
-9
lines changed

tools/testbench/include/testbench/utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ struct testbench_prm {
148148
#endif
149149
};
150150

151+
struct tb_heap_usage_record {
152+
char *module_name;
153+
int heap_max;
154+
};
155+
151156
extern int debug;
152157

153158
int tb_decode_enum(struct snd_soc_tplg_enum_control *enum_ctl, char *token);

tools/testbench/testbench.c

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,48 @@ static int parse_input_args(int argc, char **argv, struct testbench_prm *tp)
240240
return ret;
241241
}
242242

243-
static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
243+
#if CONFIG_IPC_MAJOR_4
244+
static int tb_collect_heap_usage(struct testbench_prm *tp, struct tb_heap_usage_record *records,
245+
int *count_out)
246+
{
247+
struct list_item *item;
248+
int count = 0;
249+
250+
list_for_item(item, &tp->widget_list)
251+
{
252+
struct tplg_comp_info *info = container_of(item, struct tplg_comp_info, item);
253+
uint32_t comp_id = IPC4_COMP_ID(info->module_id, info->instance_id);
254+
struct comp_dev *dev = ipc4_get_comp_dev(comp_id);
255+
256+
if (!dev || !dev->mod)
257+
continue;
258+
259+
/* In testbench environment, skip AIF/DAI because they are not real components. */
260+
if (info->type == SND_SOC_TPLG_DAPM_AIF_IN ||
261+
info->type == SND_SOC_TPLG_DAPM_AIF_OUT ||
262+
info->type == SND_SOC_TPLG_DAPM_DAI_IN ||
263+
info->type == SND_SOC_TPLG_DAPM_DAI_OUT)
264+
continue;
265+
266+
if (count >= TB_NUM_WIDGETS_SUPPORTED) {
267+
fprintf(stderr, "Error: Too many components for heap records, max %d.\n",
268+
TB_NUM_WIDGETS_SUPPORTED);
269+
break;
270+
}
271+
272+
records[count].module_name = info->name;
273+
records[count].heap_max = (int)dev->mod->priv.resources.heap_high_water_mark;
274+
count++;
275+
}
276+
277+
*count_out = count;
278+
return 0;
279+
}
280+
#endif
281+
282+
static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t,
283+
struct tb_heap_usage_record *heap_records,
284+
int heap_records_count)
244285
{
245286
long long file_cycles, pipeline_cycles;
246287
float pipeline_mcps;
@@ -295,11 +336,15 @@ static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
295336
printf("Warning: Use -d 3 or smaller value to avoid traces to increase MCPS.\n");
296337
}
297338

298-
if (delta_t)
299-
printf("Total execution time: %lld us, %.2f x realtime\n",
300-
delta_t, (float)frames_out / tp->fs_out * 1000000 / delta_t);
339+
if (heap_records_count > 0) {
340+
for (i = 0; i < heap_records_count; i++)
341+
printf("Heap usage for module %s: %d bytes\n",
342+
heap_records[i].module_name, heap_records[i].heap_max);
343+
}
301344

302-
printf("\n");
345+
if (delta_t)
346+
printf("Total execution time: %lld us, %.2f x realtime\n\n", delta_t,
347+
(float)frames_out / tp->fs_out * 1000000 / delta_t);
303348
}
304349

305350
/*
@@ -308,14 +353,16 @@ static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
308353
*/
309354
static int pipline_test(struct testbench_prm *tp)
310355
{
311-
float samples_to_ns;
312-
int dp_count = 0;
313-
struct timespec td0, td1;
356+
struct tb_heap_usage_record heap_usage_records[TB_NUM_WIDGETS_SUPPORTED];
314357
struct file_state *out_stat;
358+
struct timespec td0, td1;
315359
long long delta_t;
316360
int64_t next_control_ns;
317361
int64_t time_ns;
362+
float samples_to_ns;
318363
int err;
364+
int heap_usage_records_count = 0;
365+
int dp_count = 0;
319366

320367
/* build, run and teardown pipelines */
321368
while (dp_count < tp->dynamic_pipeline_iterations) {
@@ -396,6 +443,9 @@ static int pipline_test(struct testbench_prm *tp)
396443
tb_gettime(&td1);
397444

398445
out:
446+
#if CONFIG_IPC_MAJOR_4
447+
tb_collect_heap_usage(tp, heap_usage_records, &heap_usage_records_count);
448+
#endif
399449
err = tb_set_reset_state(tp);
400450
if (err < 0) {
401451
fprintf(stderr, "error: pipeline reset %d failed %d\n",
@@ -408,7 +458,7 @@ static int pipline_test(struct testbench_prm *tp)
408458
*/
409459
delta_t = (td1.tv_sec - td0.tv_sec) * 1000000;
410460
delta_t += (td1.tv_nsec - td0.tv_nsec) / 1000;
411-
test_pipeline_stats(tp, delta_t);
461+
test_pipeline_stats(tp, delta_t, heap_usage_records, heap_usage_records_count);
412462

413463
err = tb_free_all_pipelines(tp);
414464
if (err < 0) {

0 commit comments

Comments
 (0)