Skip to content

Commit 8fc72b9

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 8fc72b9

File tree

2 files changed

+63
-9
lines changed

2 files changed

+63
-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+
size_t 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: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,47 @@ 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+
struct tplg_comp_info *info = container_of(item, struct tplg_comp_info, item);
252+
uint32_t comp_id = IPC4_COMP_ID(info->module_id, info->instance_id);
253+
struct comp_dev *dev = ipc4_get_comp_dev(comp_id);
254+
255+
if (!dev || !dev->mod)
256+
continue;
257+
258+
/* In testbench environment, skip AIF/DAI because they are not real components. */
259+
if (info->type == SND_SOC_TPLG_DAPM_AIF_IN ||
260+
info->type == SND_SOC_TPLG_DAPM_AIF_OUT ||
261+
info->type == SND_SOC_TPLG_DAPM_DAI_IN ||
262+
info->type == SND_SOC_TPLG_DAPM_DAI_OUT)
263+
continue;
264+
265+
if (count >= TB_NUM_WIDGETS_SUPPORTED) {
266+
fprintf(stderr, "Error: Too many components for heap records, max %d.\n",
267+
TB_NUM_WIDGETS_SUPPORTED);
268+
break;
269+
}
270+
271+
records[count].module_name = info->name;
272+
records[count].heap_max = dev->mod->priv.resources.heap_high_water_mark;
273+
count++;
274+
}
275+
276+
*count_out = count;
277+
return 0;
278+
}
279+
#endif
280+
281+
static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t,
282+
struct tb_heap_usage_record *heap_records,
283+
int heap_records_count)
244284
{
245285
long long file_cycles, pipeline_cycles;
246286
float pipeline_mcps;
@@ -295,11 +335,15 @@ static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
295335
printf("Warning: Use -d 3 or smaller value to avoid traces to increase MCPS.\n");
296336
}
297337

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);
338+
if (heap_records_count > 0) {
339+
for (i = 0; i < heap_records_count; i++)
340+
printf("Heap usage for module %s: %u bytes\n",
341+
heap_records[i].module_name, (uint32_t)heap_records[i].heap_max);
342+
}
301343

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

305349
/*
@@ -308,14 +352,16 @@ static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
308352
*/
309353
static int pipline_test(struct testbench_prm *tp)
310354
{
311-
float samples_to_ns;
312-
int dp_count = 0;
313-
struct timespec td0, td1;
355+
struct tb_heap_usage_record heap_usage_records[TB_NUM_WIDGETS_SUPPORTED];
314356
struct file_state *out_stat;
357+
struct timespec td0, td1;
315358
long long delta_t;
316359
int64_t next_control_ns;
317360
int64_t time_ns;
361+
float samples_to_ns;
318362
int err;
363+
int heap_usage_records_count = 0;
364+
int dp_count = 0;
319365

320366
/* build, run and teardown pipelines */
321367
while (dp_count < tp->dynamic_pipeline_iterations) {
@@ -396,6 +442,9 @@ static int pipline_test(struct testbench_prm *tp)
396442
tb_gettime(&td1);
397443

398444
out:
445+
#if CONFIG_IPC_MAJOR_4
446+
tb_collect_heap_usage(tp, heap_usage_records, &heap_usage_records_count);
447+
#endif
399448
err = tb_set_reset_state(tp);
400449
if (err < 0) {
401450
fprintf(stderr, "error: pipeline reset %d failed %d\n",
@@ -408,7 +457,7 @@ static int pipline_test(struct testbench_prm *tp)
408457
*/
409458
delta_t = (td1.tv_sec - td0.tv_sec) * 1000000;
410459
delta_t += (td1.tv_nsec - td0.tv_nsec) / 1000;
411-
test_pipeline_stats(tp, delta_t);
460+
test_pipeline_stats(tp, delta_t, heap_usage_records, heap_usage_records_count);
412461

413462
err = tb_free_all_pipelines(tp);
414463
if (err < 0) {

0 commit comments

Comments
 (0)