Skip to content

Commit e2ea25b

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 e2ea25b

File tree

4 files changed

+92
-19
lines changed

4 files changed

+92
-19
lines changed

tools/testbench/include/testbench/utils.h

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

151+
/**
152+
* @brief Record of heap memory usage for a module.
153+
*
154+
* Stores the maximum heap usage observed for a specific module,
155+
* used for profiling and memory analysis in testbench.
156+
*/
157+
struct tb_heap_usage_record {
158+
char *module_name; /**< Name of the module */
159+
size_t heap_max; /**< Maximum heap usage in bytes */
160+
};
161+
151162
extern int debug;
152163

153164
int tb_decode_enum(struct snd_soc_tplg_enum_control *enum_ctl, char *token);
@@ -169,6 +180,18 @@ int tb_set_up_all_pipelines(struct testbench_prm *tp);
169180
int tb_setup(struct sof *sof, struct testbench_prm *tp);
170181
bool tb_is_pipeline_enabled(struct testbench_prm *tp, int pipeline_id);
171182
bool tb_schedule_pipeline_check_state(struct testbench_prm *tp);
183+
184+
/**
185+
* @brief Collect heap usage statistics for all modules.
186+
*
187+
* Iterates over the active modules in the testbench and records the maximum
188+
* heap usage for each one into the provided array.
189+
*
190+
* @param tp Pointer to testbench parameters.
191+
* @param rec Array of heap usage records to populate.
192+
* @param count Pointer to an integer that receives the number of records written.
193+
*/
194+
void tb_collect_heap_usage(struct testbench_prm *tp, struct tb_heap_usage_record *rec, int *count);
172195
void tb_debug_print(char *message);
173196
void tb_free(struct sof *sof);
174197
void tb_free_topology(struct testbench_prm *tp);

tools/testbench/testbench.c

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,9 @@ 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+
static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t,
244+
struct tb_heap_usage_record *heap_records,
245+
int heap_records_count)
244246
{
245247
long long file_cycles, pipeline_cycles;
246248
float pipeline_mcps;
@@ -284,22 +286,28 @@ static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
284286
frames_out = n_out / tp->channels_out;
285287
printf("Input sample (frame) count: %d (%d)\n", n_in, n_in / tp->channels_in);
286288
printf("Output sample (frame) count: %d (%d)\n", n_out, frames_out);
289+
if (heap_records_count > 0) {
290+
for (i = 0; i < heap_records_count; i++)
291+
printf("Heap usage for module %s: %u bytes\n",
292+
heap_records[i].module_name, (uint32_t)heap_records[i].heap_max);
293+
}
294+
295+
printf("\n");
287296
if (tp->total_cycles) {
288297
pipeline_cycles = tp->total_cycles - file_cycles;
289298
pipeline_mcps = (float)pipeline_cycles * tp->fs_out / frames_out / 1e6;
299+
if (tb_check_trace(LOG_LEVEL_DEBUG))
300+
printf("Warning: Use -d 3 or smaller value to avoid traces to increase MCPS.\n");
301+
290302
printf("Total execution cycles: %lld\n", tp->total_cycles);
291303
printf("File component cycles: %lld\n", file_cycles);
292304
printf("Pipeline cycles: %lld\n", pipeline_cycles);
293-
printf("Pipeline MCPS: %6.2f\n", pipeline_mcps);
294-
if (tb_check_trace(LOG_LEVEL_DEBUG))
295-
printf("Warning: Use -d 3 or smaller value to avoid traces to increase MCPS.\n");
305+
printf("Pipeline MCPS: %6.2f\n\n", pipeline_mcps);
296306
}
297307

298308
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);
301-
302-
printf("\n");
309+
printf("Total execution time: %lld us, %.2f x realtime\n\n", delta_t,
310+
(float)frames_out / tp->fs_out * 1000000 / delta_t);
303311
}
304312

305313
/*
@@ -308,14 +316,16 @@ static void test_pipeline_stats(struct testbench_prm *tp, long long delta_t)
308316
*/
309317
static int pipline_test(struct testbench_prm *tp)
310318
{
311-
float samples_to_ns;
312-
int dp_count = 0;
313-
struct timespec td0, td1;
319+
struct tb_heap_usage_record heap_usage_records[TB_NUM_WIDGETS_SUPPORTED];
314320
struct file_state *out_stat;
315-
long long delta_t;
321+
struct timespec td0 = {0}, td1 = {0};
322+
long long delta_t = 0;
316323
int64_t next_control_ns;
317324
int64_t time_ns;
325+
float samples_to_ns;
318326
int err;
327+
int heap_usage_records_count = 0;
328+
int dp_count = 0;
319329

320330
/* build, run and teardown pipelines */
321331
while (dp_count < tp->dynamic_pipeline_iterations) {
@@ -392,8 +402,10 @@ static int pipline_test(struct testbench_prm *tp)
392402
}
393403

394404
tb_schedule_pipeline_check_state(tp); /* Once more to flush out remaining data */
395-
396405
tb_gettime(&td1);
406+
delta_t = (td1.tv_sec - td0.tv_sec) * 1000000;
407+
delta_t += (td1.tv_nsec - td0.tv_nsec) / 1000;
408+
tb_collect_heap_usage(tp, heap_usage_records, &heap_usage_records_count);
397409

398410
out:
399411
err = tb_set_reset_state(tp);
@@ -403,12 +415,7 @@ static int pipline_test(struct testbench_prm *tp)
403415
break;
404416
}
405417

406-
/* TODO: This should be printed after reset and free to get cleaner output
407-
* but the file internal status would be lost there.
408-
*/
409-
delta_t = (td1.tv_sec - td0.tv_sec) * 1000000;
410-
delta_t += (td1.tv_nsec - td0.tv_nsec) / 1000;
411-
test_pipeline_stats(tp, delta_t);
418+
test_pipeline_stats(tp, delta_t, heap_usage_records, heap_usage_records_count);
412419

413420
err = tb_free_all_pipelines(tp);
414421
if (err < 0) {

tools/testbench/utils_ipc3.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,4 +441,9 @@ int tb_set_bytes_control(struct testbench_prm *tp, struct tb_ctl *ctl, uint32_t
441441
return 0;
442442
}
443443

444+
void tb_collect_heap_usage(struct testbench_prm *tp, struct tb_heap_usage_record *rec, int *count)
445+
{
446+
*count = 0;
447+
}
448+
444449
#endif /* CONFIG_IPC_MAJOR_3 */

tools/testbench/utils_ipc4.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#if CONFIG_IPC_MAJOR_4
66

7+
#include <sof/audio/module_adapter/module/generic.h>
78
#include <sof/audio/component_ext.h>
89
#include <sof/lib/notifier.h>
910
#include <sof/audio/component_ext.h>
@@ -702,4 +703,41 @@ int tb_set_bytes_control(struct testbench_prm *tp, struct tb_ctl *ctl, uint32_t
702703
(struct sof_abi_hdr *)data);
703704
}
704705

706+
void tb_collect_heap_usage(struct testbench_prm *tp, struct tb_heap_usage_record *records,
707+
int *count_out)
708+
{
709+
struct list_item *item;
710+
size_t hwm;
711+
int count = 0;
712+
713+
list_for_item(item, &tp->widget_list) {
714+
struct tplg_comp_info *info = container_of(item, struct tplg_comp_info, item);
715+
uint32_t comp_id = IPC4_COMP_ID(info->module_id, info->instance_id);
716+
struct comp_dev *dev = ipc4_get_comp_dev(comp_id);
717+
718+
if (!dev || !dev->mod)
719+
continue;
720+
721+
/* In testbench environment, skip AIF/DAI because they are not real components. */
722+
if (info->type == SND_SOC_TPLG_DAPM_AIF_IN ||
723+
info->type == SND_SOC_TPLG_DAPM_AIF_OUT ||
724+
info->type == SND_SOC_TPLG_DAPM_DAI_IN ||
725+
info->type == SND_SOC_TPLG_DAPM_DAI_OUT)
726+
continue;
727+
728+
if (count >= TB_NUM_WIDGETS_SUPPORTED) {
729+
fprintf(stderr, "Error: Too many components for heap records, max %d.\n",
730+
TB_NUM_WIDGETS_SUPPORTED);
731+
break;
732+
}
733+
734+
module_adapter_heap_usage(dev->mod, &hwm);
735+
records[count].module_name = info->name;
736+
records[count].heap_max = hwm;
737+
count++;
738+
}
739+
740+
*count_out = count;
741+
}
742+
705743
#endif /* CONFIG_IPC_MAJOR_4 */

0 commit comments

Comments
 (0)