Sound Open Firmware
Loading...
Searching...
No Matches
perf_cnt.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2019 Intel Corporation. All rights reserved.
4 *
5 * Author: Marcin Maka <marcin.maka@linux.intel.com>
6 */
7
14#ifndef __SOF_LIB_PERF_CNT_H__
15#define __SOF_LIB_PERF_CNT_H__
16
17#include <rtos/timer.h>
19
20#if CONFIG_PERFORMANCE_COUNTERS
21
22#define perf_cnt_trace(ctx, pcd) \
23 tr_info(ctx, "perf plat last %u peak %u cpu last %u, peak %u", \
24 (uint32_t)((pcd)->plat_delta_last), \
25 (uint32_t)((pcd)->plat_delta_peak), \
26 (uint32_t)((pcd)->cpu_delta_last), \
27 (uint32_t)((pcd)->cpu_delta_peak))
28
30#define perf_cnt_clear(pcd) memset((pcd), 0, sizeof(struct perf_cnt_data))
31
32/* NOTE: Zephyr's arch_timing_counter_get() might not be implemented
33 * for a particular platform. In this case let's fallback to use
34 * Zephyr's k_cycle_get_64(). This will result in both "platform" and
35 * "cpu" timestamps to be equal.
36 */
37#ifdef __ZEPHYR__
38 #include <zephyr/timing/timing.h>
39 #ifdef CONFIG_TIMING_FUNCTIONS
40 #define perf_cnt_get_cpu_ts timing_counter_get
41 #else
42 #define perf_cnt_get_cpu_ts sof_cycle_get_64
43 #endif /* CONFIG_TIMING_FUNCTIONS */
44#else
45 #define perf_cnt_get_cpu_ts() timer_get_system(cpu_timer_get())
46#endif /* __ZEPHYR__ */
47
49#define perf_cnt_init(pcd) do { \
50 (pcd)->plat_ts = sof_cycle_get_64(); \
51 (pcd)->cpu_ts = perf_cnt_get_cpu_ts(); \
52 } while (0)
53
54/* Trace macros that can be used as trace_m argument of the perf_cnt_stamp()
55 * to trace PCD values if the last arch timer reading exceeds the previous
56 * peak value.
57 *
58 * arg passed to perf_cnt_stamp() is forwarded to the trace_m() macro
59 * as the second argument.
60 */
61
63#define perf_trace_null(pcd, arg)
64
67#define perf_trace_simple(pcd, arg) perf_cnt_trace(arg, pcd)
68
69/* perf measurement windows size 2^x */
70#define PERF_CNT_CHECK_WINDOW_SIZE 10
71#define task_perf_avg_info(pcd, task_p, class) \
72 tr_info(task_p, "perf_cycle task %p, %pU cpu avg %u peak %u",\
73 class, (class)->uid, \
74 (uint32_t)((pcd)->cpu_delta_sum), \
75 (uint32_t)((pcd)->cpu_delta_peak))
76#define task_perf_cnt_avg(pcd, trace_m, arg, class) do { \
77 (pcd)->cpu_delta_sum += (pcd)->cpu_delta_last; \
78 if (!(++(pcd)->period_cnt & MASK(PERF_CNT_CHECK_WINDOW_SIZE - 1, 0))) { \
79 (pcd)->cpu_delta_sum >>= PERF_CNT_CHECK_WINDOW_SIZE; \
80 if ((pcd)->period_cnt & BIT(PERF_CNT_CHECK_WINDOW_SIZE)) \
81 trace_m(pcd, arg, class); \
82 (pcd)->cpu_delta_sum = 0; \
83 (pcd)->plat_delta_peak = 0; \
84 (pcd)->cpu_delta_peak = 0; \
85 } \
86 } while (0)
87
96#define perf_cnt_average(pcd, trace_m, arg) do { \
97 (pcd)->cpu_delta_sum += (pcd)->cpu_delta_last; \
98 if (!(++(pcd)->period_cnt & MASK(PERF_CNT_CHECK_WINDOW_SIZE - 1, 0))) { \
99 (pcd)->cpu_delta_sum >>= PERF_CNT_CHECK_WINDOW_SIZE; \
100 (pcd)->peak_mcps_period_cnt &= MASK(PERF_CNT_CHECK_WINDOW_SIZE - 1, 0); \
101 if ((pcd)->period_cnt & BIT(PERF_CNT_CHECK_WINDOW_SIZE)) { \
102 trace_m(pcd, arg); \
103 } \
104 (pcd)->cpu_delta_sum = 0; \
105 (pcd)->plat_delta_peak = 0; \
106 (pcd)->cpu_delta_peak = 0; \
107 (pcd)->peak_mcps_period_cnt = 0; \
108 } \
109 } while (0)
110
119#define perf_cnt_stamp(pcd, trace_m, arg) do { \
120 uint32_t plat_ts = \
121 (uint32_t)sof_cycle_get_64(); \
122 uint32_t cpu_ts = \
123 (uint32_t)perf_cnt_get_cpu_ts(); \
124 (pcd)->plat_delta_last = plat_ts - (pcd)->plat_ts; \
125 (pcd)->cpu_delta_last = cpu_ts - (pcd)->cpu_ts; \
126 if ((pcd)->plat_delta_last > (pcd)->plat_delta_peak) { \
127 (pcd)->plat_delta_peak = (pcd)->plat_delta_last; \
128 (pcd)->peak_mcps_period_cnt = (pcd)->period_cnt; \
129 } \
130 if ((pcd)->cpu_delta_last > (pcd)->cpu_delta_peak) { \
131 (pcd)->cpu_delta_peak = (pcd)->cpu_delta_last; \
132 trace_m(pcd, arg); \
133 } \
134 } while (0)
135
156#define perf_tic(pcd) \
157 perf_cnt_init(pcd)
158
164#define perf_toc(pcd, comp) do { \
165 perf_cnt_stamp(pcd, perf_trace_null, NULL); \
166 perf_trace_simple(pcd, trace_comp_get_tr_ctx(comp)); \
167 } while (0)
168
169#else
170#define perf_cnt_clear(pcd)
171#define perf_cnt_init(pcd)
172#define perf_cnt_stamp(pcd, trace_m, arg)
173#define perf_cnt_average(pcd, trace_m, arg)
174#endif
175
176#endif /* __SOF_LIB_PERF_CNT_H__ */
Performance counter data, without the timer based helpers.
RTOS cycle counter, hardware timer, and timestamp utilities.