Skip to content

Commit 286cefb

Browse files
vlad-kulikovnashif
authored andcommitted
smf: improve sibling transitions speed
Sibling transitions are now detected in smf_set_state() when source and destination share the same parent, removing the need for states to flag the sibling transition explicitly. Restore include/zephyr/smf.h and lib/smf/Kconfig to match main so this change only carries the functional update in lib/smf/smf.c, and add a micro-benchmark test. For accurate statistics, run the test on a board. Micro-benchmark setup - Board: NUCLEO-F746ZG (STM32F746, ~192 MHz) - 200000 iterations per state transition - Simple HSM (letters are nodes; R is root): === SMF transition micro-benchmark === R / \ A B / \ / \ C D E F / \ \ G H J Current smf_set_state: ====================== Sibling Transitions (A->B) : 459 cycles/transition (2390 ns) (C->D) : 482 cycles/transition (2510 ns) (G->H) : 522 cycles/transition (2718 ns) Other Transitions (G<->G) : 237 cycles/transition (1234 ns) (C->G) : 343 cycles/transition (1786 ns) (A->H) : 452 cycles/transition (2354 ns) (G->D) : 651 cycles/transition (3390 ns) (D->E) : 752 cycles/transition (3916 ns) (J->D) : 893 cycles/transition (4651 ns) (J->G) : 1077 cycles/transition (5609 ns) New smf_set_state: ================== Sibling Transitions (A->B) : 356 cycles/transition (1854 ns)(22% faster) (C->D) : 356 cycles/transition (1854 ns)(26% faster) (G->H) : 356 cycles/transition (1854 ns)(32% faster) Other Transitions (G<->G) : 258 cycles/transition (1343 ns)(9% slower) (C->G) : 356 cycles/transition (1854 ns)(4% slower) (A->H) : 464 cycles/transition (2416 ns)(3% slower) (G->D) : 707 cycles/transition (3682 ns)(9% slower) (D->E) : 797 cycles/transition (4151 ns)(6% slower) (J->D) : 970 cycles/transition (5052 ns)(9% slower) (J->G) : 1157 cycles/transition (6026 ns)(8% slower) This change makes sibling transitions deterministic and cheaper (356 cycles on nsim), at the cost of a small increase for deeper/LCA transitions (~7–9%). This is a net win for state machines that mostly hop between siblings. Signed-off-by: Vladislav Kulikov <[email protected]>
1 parent e8d8979 commit 286cefb

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

lib/smf/smf.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,10 @@ void smf_set_state(struct smf_ctx *const ctx, const struct smf_state *new_state)
300300
#ifdef CONFIG_SMF_ANCESTOR_SUPPORT
301301
const struct smf_state *topmost;
302302

303-
if (is_descendant_of(ctx->executing, new_state)) {
303+
if (ctx->executing != new_state && ctx->executing->parent == new_state->parent) {
304+
/* Optimize sibling transitions (different states under same parent) */
305+
topmost = ctx->executing->parent;
306+
} else if (is_descendant_of(ctx->executing, new_state)) {
304307
/* new state is a parent of where we are now*/
305308
topmost = new_state;
306309
} else if (is_descendant_of(new_state, ctx->executing)) {

0 commit comments

Comments
 (0)