diff options
author | Damjan Marion <damarion@cisco.com> | 2021-12-02 17:08:02 +0100 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2021-12-02 17:49:49 +0000 |
commit | e31c48a66b966fa326a5ca813892201e7e3e054b (patch) | |
tree | 49c81986a9b0392c8dd5f0f35e3112a88fb5746e /src/plugins/perfmon | |
parent | 3323e2018d6d736a25b15902bc85f559ea98adb5 (diff) |
perfmon: compile dispatch wrapper once for each number of counters
A bit ugly, but generates faster and less noisy code which
should be important for this particular use case.
Type: improvement
Change-Id: If2bba947dac33ffedb4236a5b3fb50fc783668e1
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/plugins/perfmon')
-rw-r--r-- | src/plugins/perfmon/dispatch_wrapper.c | 56 | ||||
-rw-r--r-- | src/plugins/perfmon/perfmon.c | 4 | ||||
-rw-r--r-- | src/plugins/perfmon/perfmon.h | 2 |
3 files changed, 27 insertions, 35 deletions
diff --git a/src/plugins/perfmon/dispatch_wrapper.c b/src/plugins/perfmon/dispatch_wrapper.c index 64df7f56928..3ae1219fe04 100644 --- a/src/plugins/perfmon/dispatch_wrapper.c +++ b/src/plugins/perfmon/dispatch_wrapper.c @@ -28,38 +28,13 @@ static_always_inline void perfmon_read_pmcs (u64 *counters, u32 *indexes, u8 n_counters) { - switch (n_counters) - { - case 12: - counters[11] = _rdpmc (indexes[11] - 1); - case 11: - counters[10] = _rdpmc (indexes[10] - 1); - case 10: - counters[9] = _rdpmc (indexes[9] - 1); - case 9: - counters[8] = _rdpmc (indexes[8] - 1); - case 8: - counters[7] = _rdpmc (indexes[7] - 1); - case 7: - counters[6] = _rdpmc (indexes[6] - 1); - case 6: - counters[5] = _rdpmc (indexes[5] - 1); - case 5: - counters[4] = _rdpmc (indexes[4] - 1); - case 4: - counters[3] = _rdpmc (indexes[3] - 1); - case 3: - counters[2] = _rdpmc (indexes[2] - 1); - case 2: - counters[1] = _rdpmc (indexes[1] - 1); - case 1: - counters[0] = _rdpmc (indexes[0] - 1); - } + for (int i = 0; i < n_counters; i++) + counters[i] = _rdpmc (indexes[i] - 1); } -uword -perfmon_dispatch_wrapper (vlib_main_t *vm, vlib_node_runtime_t *node, - vlib_frame_t *frame) +static_always_inline uword +perfmon_dispatch_wrapper_inline (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_frame_t *frame, u8 n_events) { perfmon_main_t *pm = &perfmon_main; perfmon_thread_runtime_t *rt = @@ -67,8 +42,6 @@ perfmon_dispatch_wrapper (vlib_main_t *vm, vlib_node_runtime_t *node, perfmon_node_stats_t *s = vec_elt_at_index (rt->node_stats, node->node_index); - u8 n_events = rt->n_events; - struct { u64 t[2][PERF_MAX_EVENTS]; @@ -102,3 +75,22 @@ perfmon_dispatch_wrapper (vlib_main_t *vm, vlib_node_runtime_t *node, return rv; } + +#define foreach_n_events \ + _ (1) _ (2) _ (3) _ (4) _ (5) _ (6) _ (7) _ (8) _ (9) _ (10) _ (11) _ (12) + +#define _(x) \ + static uword perfmon_dispatch_wrapper##x ( \ + vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) \ + { \ + return perfmon_dispatch_wrapper_inline (vm, node, frame, x); \ + } + +foreach_n_events +#undef _ + + vlib_node_function_t *perfmon_dispatch_wrappers[PERF_MAX_EVENTS + 1] = { +#define _(x) [x] = &perfmon_dispatch_wrapper##x, + foreach_n_events +#undef _ + }; diff --git a/src/plugins/perfmon/perfmon.c b/src/plugins/perfmon/perfmon.c index 09178929218..0f89708567c 100644 --- a/src/plugins/perfmon/perfmon.c +++ b/src/plugins/perfmon/perfmon.c @@ -285,8 +285,8 @@ perfmon_start (vlib_main_t *vm, perfmon_bundle_t *b) } for (int i = 0; i < vlib_get_n_threads (); i++) - vlib_node_set_dispatch_wrapper (vlib_get_main_by_index (i), - perfmon_dispatch_wrapper); + vlib_node_set_dispatch_wrapper ( + vlib_get_main_by_index (i), perfmon_dispatch_wrappers[b->n_events]); } pm->sample_time = vlib_time_now (vm); pm->is_running = 1; diff --git a/src/plugins/perfmon/perfmon.h b/src/plugins/perfmon/perfmon.h index 5003e59015e..58d971f559a 100644 --- a/src/plugins/perfmon/perfmon.h +++ b/src/plugins/perfmon/perfmon.h @@ -78,7 +78,7 @@ typedef struct } perfmon_instance_type_t; struct perfmon_source; -vlib_node_function_t perfmon_dispatch_wrapper; +extern vlib_node_function_t *perfmon_dispatch_wrappers[PERF_MAX_EVENTS + 1]; typedef clib_error_t *(perfmon_source_init_fn_t) (vlib_main_t *vm, struct perfmon_source *); |