← All Use Cases
📡
Full Factorial Design

RTOS Task Priority

Full factorial of task priority levels, tick rate, stack size, and preemption threshold for latency and utilization

Summary

This experiment investigates rtos task priority. Full factorial of task priority levels, tick rate, stack size, and preemption threshold for latency and utilization.

The design varies 4 factors: task priority levels (levels), ranging from 4 to 16, tick rate hz (Hz), ranging from 100 to 1000, stack size bytes (bytes), ranging from 512 to 4096, and preemption threshold (level), ranging from 1 to 8. The goal is to optimize 2 responses: worst case latency us (us) (minimize) and cpu utilization pct (%) (maximize). Fixed conditions held constant across all runs include rtos = freertos, mcu clock = 240MHz.

A full factorial design was used to explore all 16 possible combinations of the 4 factors at two levels. This guarantees that every main effect and interaction can be estimated independently, at the cost of a larger experiment (16 runs).

Quadratic response surface models were fitted to capture potential curvature and factor interactions. The RSM contour plots below visualize how pairs of factors jointly affect each response.

Key Findings

For worst case latency us, the most influential factors were tick rate hz (48.8%), preemption threshold (26.5%), stack size bytes (16.7%). The best observed value was 26.0 (at task priority levels = 4, tick rate hz = 1000, stack size bytes = 512).

For cpu utilization pct, the most influential factors were preemption threshold (34.6%), stack size bytes (32.7%), tick rate hz (29.4%). The best observed value was 90.0 (at task priority levels = 16, tick rate hz = 100, stack size bytes = 512).

Recommended Next Steps

Experimental Setup

Factors

FactorLowHighUnit
task_priority_levels416levels
tick_rate_hz1001000Hz
stack_size_bytes5124096bytes
preemption_threshold18level

Fixed: rtos = freertos, mcu_clock = 240MHz

Responses

ResponseDirectionUnit
worst_case_latency_us↓ minimizeus
cpu_utilization_pct↑ maximize%

Configuration

use_cases/69_rtos_task_priority/config.json
{ "metadata": { "name": "RTOS Task Priority", "description": "Full factorial of task priority levels, tick rate, stack size, and preemption threshold for latency and utilization" }, "factors": [ { "name": "task_priority_levels", "levels": [ "4", "16" ], "type": "continuous", "unit": "levels" }, { "name": "tick_rate_hz", "levels": [ "100", "1000" ], "type": "continuous", "unit": "Hz" }, { "name": "stack_size_bytes", "levels": [ "512", "4096" ], "type": "continuous", "unit": "bytes" }, { "name": "preemption_threshold", "levels": [ "1", "8" ], "type": "continuous", "unit": "level" } ], "fixed_factors": { "rtos": "freertos", "mcu_clock": "240MHz" }, "responses": [ { "name": "worst_case_latency_us", "optimize": "minimize", "unit": "us" }, { "name": "cpu_utilization_pct", "optimize": "maximize", "unit": "%" } ], "settings": { "operation": "full_factorial", "test_script": "use_cases/69_rtos_task_priority/sim.sh" } }

Experimental Matrix

The Full Factorial Design produces 16 runs. Each row is one experiment with specific factor settings.

Runtask_priority_levelstick_rate_hzstack_size_bytespreemption_threshold
14100040968
2161005128
3410005128
44100040961
516100040961
61610040961
71610005121
8161005121
941005128
10410040961
111610005128
1216100040968
13410005121
141610040968
1541005121
16410040968

Step-by-Step Workflow

1

Preview the design

Terminal
$ doe info --config use_cases/69_rtos_task_priority/config.json
2

Generate the runner script

Terminal
$ doe generate --config use_cases/69_rtos_task_priority/config.json \ --output use_cases/69_rtos_task_priority/results/run.sh --seed 42
3

Execute the experiments

Terminal
$ bash use_cases/69_rtos_task_priority/results/run.sh
4

Analyze results

Terminal
$ doe analyze --config use_cases/69_rtos_task_priority/config.json
5

Get optimization recommendations

Terminal
$ doe optimize --config use_cases/69_rtos_task_priority/config.json
6

Multi-objective optimization

With 2 competing responses, use --multi to find the best compromise via Derringer–Suich desirability.

Terminal
$ doe optimize --config use_cases/69_rtos_task_priority/config.json --multi
7

Generate the HTML report

Terminal
$ doe report --config use_cases/69_rtos_task_priority/config.json \ --output use_cases/69_rtos_task_priority/results/report.html

Features Exercised

FeatureValue
Design typefull_factorial
Factor typescontinuous (all 4)
Arg styledouble-dash
Responses2 (worst_case_latency_us ↓, cpu_utilization_pct ↑)
Total runs16

Analysis Results

Generated from actual experiment runs using the DOE Helper Tool.

Response: worst_case_latency_us

Top factors: tick_rate_hz (48.8%), preemption_threshold (26.5%), stack_size_bytes (16.7%).

ANOVA

SourceDFSSMSFp-value
SourceDFSSMSFp-value
task_priority_levels110.562510.56250.0100.9235
tick_rate_hz1390.0625390.06250.3760.5663
stack_size_bytes145.562545.56250.0440.8422
preemption_threshold1115.5625115.56250.1120.7520
task_priority_levels*tick_rate_hz1370.5625370.56250.3580.5759
task_priority_levels*stack_size_bytes1855.5625855.56250.8260.4052
task_priority_levels*preemption_threshold145.562545.56250.0440.8422
tick_rate_hz*stack_size_bytes1473.0625473.06250.4570.5292
tick_rate_hz*preemption_threshold1175.5625175.56250.1690.6977
stack_size_bytes*preemption_threshold11580.06251580.06251.5250.2717
Error55180.81251036.1625
Total159242.9375616.1958

Pareto Chart

Pareto chart for worst_case_latency_us

Main Effects Plot

Main effects plot for worst_case_latency_us

Normal Probability Plot of Effects

Normal probability plot for worst_case_latency_us

Half-Normal Plot of Effects

Half-normal plot for worst_case_latency_us

Model Diagnostics

Model diagnostics for worst_case_latency_us

Response: cpu_utilization_pct

Top factors: preemption_threshold (34.6%), stack_size_bytes (32.7%), tick_rate_hz (29.4%).

ANOVA

SourceDFSSMSFp-value
SourceDFSSMSFp-value
task_priority_levels10.25000.25000.0010.9814
tick_rate_hz120.250020.25000.0490.8341
stack_size_bytes125.000025.00000.0600.8160
preemption_threshold128.090028.09000.0680.8053
task_priority_levels*tick_rate_hz141.602541.60250.1000.7645
task_priority_levels*stack_size_bytes1678.6025678.60251.6320.2575
task_priority_levels*preemption_threshold163.202563.20250.1520.7127
tick_rate_hz*stack_size_bytes1172.9225172.92250.4160.5474
tick_rate_hz*preemption_threshold122.562522.56250.0540.8250
stack_size_bytes*preemption_threshold1460.1025460.10251.1070.3410
Error52078.6325415.7265
Total153591.2175239.4145

Pareto Chart

Pareto chart for cpu_utilization_pct

Main Effects Plot

Main effects plot for cpu_utilization_pct

Normal Probability Plot of Effects

Normal probability plot for cpu_utilization_pct

Half-Normal Plot of Effects

Half-normal plot for cpu_utilization_pct

Model Diagnostics

Model diagnostics for cpu_utilization_pct

Response Surface Plots

3D surfaces fitted with quadratic RSM. Red dots are observed data points.

cpu utilization pct stack size bytes vs preemption threshold

RSM surface: cpu utilization pct stack size bytes vs preemption threshold

cpu utilization pct task priority levels vs preemption threshold

RSM surface: cpu utilization pct task priority levels vs preemption threshold

cpu utilization pct task priority levels vs stack size bytes

RSM surface: cpu utilization pct task priority levels vs stack size bytes

cpu utilization pct task priority levels vs tick rate hz

RSM surface: cpu utilization pct task priority levels vs tick rate hz

cpu utilization pct tick rate hz vs preemption threshold

RSM surface: cpu utilization pct tick rate hz vs preemption threshold

cpu utilization pct tick rate hz vs stack size bytes

RSM surface: cpu utilization pct tick rate hz vs stack size bytes

worst case latency us stack size bytes vs preemption threshold

RSM surface: worst case latency us stack size bytes vs preemption threshold

worst case latency us task priority levels vs preemption threshold

RSM surface: worst case latency us task priority levels vs preemption threshold

worst case latency us task priority levels vs stack size bytes

RSM surface: worst case latency us task priority levels vs stack size bytes

worst case latency us task priority levels vs tick rate hz

RSM surface: worst case latency us task priority levels vs tick rate hz

worst case latency us tick rate hz vs preemption threshold

RSM surface: worst case latency us tick rate hz vs preemption threshold

worst case latency us tick rate hz vs stack size bytes

RSM surface: worst case latency us tick rate hz vs stack size bytes

Multi-Objective Optimization

When responses compete, Derringer–Suich desirability finds the best compromise. Each response is scaled to a 0–1 desirability, then combined via a weighted geometric mean.

Overall Desirability
D = 0.9166

Per-Response Desirability

ResponseWeightDesirabilityPredictedDir
worst_case_latency_us 1.0
0.8625
34.00 0.8625 34.00 us
cpu_utilization_pct 1.5
0.9545
90.00 0.9545 90.00 %

Recommended Settings

FactorValue
task_priority_levels16 levels
tick_rate_hz100 Hz
stack_size_bytes4096 bytes
preemption_threshold8 level

Source: from observed run #11

Trade-off Summary

Sacrifice = how much worse than single-objective best.

ResponsePredictedBest ObservedSacrifice
cpu_utilization_pct90.0090.00+0.00

Top 3 Runs by Desirability

RunDFactor Settings
#120.8217task_priority_levels=4, tick_rate_hz=100, stack_size_bytes=512, preemption_threshold=1
#70.7018task_priority_levels=4, tick_rate_hz=1000, stack_size_bytes=512, preemption_threshold=8

Model Quality

ResponseType
cpu_utilization_pct0.3362linear

Full Multi-Objective Output

doe optimize --multi
============================================================ MULTI-OBJECTIVE OPTIMIZATION Method: Derringer-Suich Desirability Function ============================================================ Overall desirability: D = 0.9166 Response Weight Desirability Predicted Direction --------------------------------------------------------------------- worst_case_latency_us 1.0 0.8625 34.00 us ↓ cpu_utilization_pct 1.5 0.9545 90.00 % ↑ Recommended settings: task_priority_levels = 16 levels tick_rate_hz = 100 Hz stack_size_bytes = 4096 bytes preemption_threshold = 8 level (from observed run #11) Trade-off summary: worst_case_latency_us: 34.00 (best observed: 26.00, sacrifice: +8.00) cpu_utilization_pct: 90.00 (best observed: 90.00, sacrifice: +0.00) Model quality: worst_case_latency_us: R² = 0.1531 (linear) cpu_utilization_pct: R² = 0.3362 (linear) Top 3 observed runs by overall desirability: 1. Run #11 (D=0.9166): task_priority_levels=16, tick_rate_hz=100, stack_size_bytes=4096, preemption_threshold=8 2. Run #12 (D=0.8217): task_priority_levels=4, tick_rate_hz=100, stack_size_bytes=512, preemption_threshold=1 3. Run #7 (D=0.7018): task_priority_levels=4, tick_rate_hz=1000, stack_size_bytes=512, preemption_threshold=8

Full Analysis Output

doe analyze
=== Main Effects: worst_case_latency_us === Factor Effect Std Error % Contribution -------------------------------------------------------------- tick_rate_hz 9.8750 6.2058 48.8% preemption_threshold -5.3750 6.2058 26.5% stack_size_bytes 3.3750 6.2058 16.7% task_priority_levels -1.6250 6.2058 8.0% === ANOVA Table: worst_case_latency_us === Source DF SS MS F p-value ----------------------------------------------------------------------------- task_priority_levels 1 10.5625 10.5625 0.010 0.9235 tick_rate_hz 1 390.0625 390.0625 0.376 0.5663 stack_size_bytes 1 45.5625 45.5625 0.044 0.8422 preemption_threshold 1 115.5625 115.5625 0.112 0.7520 task_priority_levels*tick_rate_hz 1 370.5625 370.5625 0.358 0.5759 task_priority_levels*stack_size_bytes 1 855.5625 855.5625 0.826 0.4052 task_priority_levels*preemption_threshold 1 45.5625 45.5625 0.044 0.8422 tick_rate_hz*stack_size_bytes 1 473.0625 473.0625 0.457 0.5292 tick_rate_hz*preemption_threshold 1 175.5625 175.5625 0.169 0.6977 stack_size_bytes*preemption_threshold 1 1580.0625 1580.0625 1.525 0.2717 Error 5 5180.8125 1036.1625 Total 15 9242.9375 616.1958 === Interaction Effects: worst_case_latency_us === Factor A Factor B Interaction % Contribution ------------------------------------------------------------------------ stack_size_bytes preemption_threshold -19.8750 30.6% task_priority_levels stack_size_bytes -14.6250 22.5% tick_rate_hz stack_size_bytes 10.8750 16.7% task_priority_levels tick_rate_hz -9.6250 14.8% tick_rate_hz preemption_threshold 6.6250 10.2% task_priority_levels preemption_threshold -3.3750 5.2% === Summary Statistics: worst_case_latency_us === task_priority_levels: Level N Mean Std Min Max ------------------------------------------------------------ 16 8 64.7500 29.0898 26.0000 105.0000 4 8 63.1250 21.7416 34.0000 94.0000 tick_rate_hz: Level N Mean Std Min Max ------------------------------------------------------------ 100 8 59.0000 22.0713 34.0000 94.0000 1000 8 68.8750 27.8846 26.0000 105.0000 stack_size_bytes: Level N Mean Std Min Max ------------------------------------------------------------ 4096 8 62.2500 23.8492 26.0000 96.0000 512 8 65.6250 27.2970 34.0000 105.0000 preemption_threshold: Level N Mean Std Min Max ------------------------------------------------------------ 1 8 66.6250 30.1090 26.0000 105.0000 8 8 61.2500 19.9338 34.0000 96.0000 === Main Effects: cpu_utilization_pct === Factor Effect Std Error % Contribution -------------------------------------------------------------- preemption_threshold -2.6500 3.8683 34.6% stack_size_bytes 2.5000 3.8683 32.7% tick_rate_hz -2.2500 3.8683 29.4% task_priority_levels -0.2500 3.8683 3.3% === ANOVA Table: cpu_utilization_pct === Source DF SS MS F p-value ----------------------------------------------------------------------------- task_priority_levels 1 0.2500 0.2500 0.001 0.9814 tick_rate_hz 1 20.2500 20.2500 0.049 0.8341 stack_size_bytes 1 25.0000 25.0000 0.060 0.8160 preemption_threshold 1 28.0900 28.0900 0.068 0.8053 task_priority_levels*tick_rate_hz 1 41.6025 41.6025 0.100 0.7645 task_priority_levels*stack_size_bytes 1 678.6025 678.6025 1.632 0.2575 task_priority_levels*preemption_threshold 1 63.2025 63.2025 0.152 0.7127 tick_rate_hz*stack_size_bytes 1 172.9225 172.9225 0.416 0.5474 tick_rate_hz*preemption_threshold 1 22.5625 22.5625 0.054 0.8250 stack_size_bytes*preemption_threshold 1 460.1025 460.1025 1.107 0.3410 Error 5 2078.6325 415.7265 Total 15 3591.2175 239.4145 === Interaction Effects: cpu_utilization_pct === Factor A Factor B Interaction % Contribution ------------------------------------------------------------------------ task_priority_levels stack_size_bytes 13.0250 32.6% stack_size_bytes preemption_threshold 10.7250 26.9% tick_rate_hz stack_size_bytes -6.5750 16.5% task_priority_levels preemption_threshold -3.9750 10.0% task_priority_levels tick_rate_hz -3.2250 8.1% tick_rate_hz preemption_threshold -2.3750 6.0% === Summary Statistics: cpu_utilization_pct === task_priority_levels: Level N Mean Std Min Max ------------------------------------------------------------ 16 8 57.9625 15.2656 37.9000 77.1000 4 8 57.7125 16.7319 34.4000 90.0000 tick_rate_hz: Level N Mean Std Min Max ------------------------------------------------------------ 100 8 58.9625 18.1725 34.4000 90.0000 1000 8 56.7125 13.4126 40.1000 77.1000 stack_size_bytes: Level N Mean Std Min Max ------------------------------------------------------------ 4096 8 56.5875 15.1936 34.4000 77.1000 512 8 59.0875 16.6917 37.9000 90.0000 preemption_threshold: Level N Mean Std Min Max ------------------------------------------------------------ 1 8 59.1625 20.8480 34.4000 90.0000 8 8 56.5125 8.6243 43.0000 69.2000

Optimization Recommendations

doe optimize
=== Optimization: worst_case_latency_us === Direction: minimize Best observed run: #12 task_priority_levels = 4 tick_rate_hz = 1000 stack_size_bytes = 512 preemption_threshold = 8 Value: 26.0 RSM Model (linear, R² = 0.2412, Adj R² = -0.0347): Coefficients: intercept +63.9375 task_priority_levels +0.0625 tick_rate_hz +3.4375 stack_size_bytes -7.0625 preemption_threshold -8.8125 RSM Model (quadratic, R² = 0.7357, Adj R² = -2.9652): Coefficients: intercept +12.7875 task_priority_levels +0.0625 tick_rate_hz +3.4375 stack_size_bytes -7.0625 preemption_threshold -8.8125 task_priority_levels*tick_rate_hz +13.3125 task_priority_levels*stack_size_bytes -4.1875 task_priority_levels*preemption_threshold -4.9375 tick_rate_hz*stack_size_bytes -4.0625 tick_rate_hz*preemption_threshold -7.0625 stack_size_bytes*preemption_threshold -0.3125 task_priority_levels^2 +12.7875 tick_rate_hz^2 +12.7875 stack_size_bytes^2 +12.7875 preemption_threshold^2 +12.7875 Curvature analysis: tick_rate_hz coef=+12.7875 convex (has a minimum) stack_size_bytes coef=+12.7875 convex (has a minimum) preemption_threshold coef=+12.7875 convex (has a minimum) task_priority_levels coef=+12.7875 convex (has a minimum) Notable interactions: task_priority_levels*tick_rate_hz coef=+13.3125 (synergistic) tick_rate_hz*preemption_threshold coef=-7.0625 (antagonistic) task_priority_levels*preemption_threshold coef=-4.9375 (antagonistic) task_priority_levels*stack_size_bytes coef=-4.1875 (antagonistic) tick_rate_hz*stack_size_bytes coef=-4.0625 (antagonistic) stack_size_bytes*preemption_threshold coef=-0.3125 (antagonistic) Predicted optimum (from linear model, at observed points): task_priority_levels = 16 tick_rate_hz = 1000 stack_size_bytes = 512 preemption_threshold = 1 Predicted value: 83.3125 Surface optimum (via L-BFGS-B, linear model): task_priority_levels = 4 tick_rate_hz = 100 stack_size_bytes = 4096 preemption_threshold = 8 Predicted value: 44.5625 Model quality: Weak fit — consider adding center points or using a different design. Factor importance: 1. preemption_threshold (effect: -17.6, contribution: 45.5%) 2. stack_size_bytes (effect: 14.1, contribution: 36.5%) 3. tick_rate_hz (effect: 6.9, contribution: 17.7%) 4. task_priority_levels (effect: -0.1, contribution: 0.3%) === Optimization: cpu_utilization_pct === Direction: maximize Best observed run: #11 task_priority_levels = 16 tick_rate_hz = 100 stack_size_bytes = 512 preemption_threshold = 8 Value: 90.0 RSM Model (linear, R² = 0.2708, Adj R² = 0.0057): Coefficients: intercept +57.8375 task_priority_levels -1.1875 tick_rate_hz -4.4250 stack_size_bytes +0.5125 preemption_threshold +6.2875 RSM Model (quadratic, R² = 0.7445, Adj R² = -2.8327): Coefficients: intercept +11.5675 task_priority_levels -1.1875 tick_rate_hz -4.4250 stack_size_bytes +0.5125 preemption_threshold +6.2875 task_priority_levels*tick_rate_hz -9.8250 task_priority_levels*stack_size_bytes -0.6125 task_priority_levels*preemption_threshold -1.6375 tick_rate_hz*stack_size_bytes +1.9500 tick_rate_hz*preemption_threshold +1.0000 stack_size_bytes*preemption_threshold +1.3875 task_priority_levels^2 +11.5675 tick_rate_hz^2 +11.5675 stack_size_bytes^2 +11.5675 preemption_threshold^2 +11.5675 Curvature analysis: preemption_threshold coef=+11.5675 convex (has a minimum) task_priority_levels coef=+11.5675 convex (has a minimum) tick_rate_hz coef=+11.5675 convex (has a minimum) stack_size_bytes coef=+11.5675 convex (has a minimum) Notable interactions: task_priority_levels*tick_rate_hz coef=-9.8250 (antagonistic) tick_rate_hz*stack_size_bytes coef=+1.9500 (synergistic) task_priority_levels*preemption_threshold coef=-1.6375 (antagonistic) stack_size_bytes*preemption_threshold coef=+1.3875 (synergistic) tick_rate_hz*preemption_threshold coef=+1.0000 (synergistic) task_priority_levels*stack_size_bytes coef=-0.6125 (antagonistic) Predicted optimum (from linear model, at observed points): task_priority_levels = 4 tick_rate_hz = 100 stack_size_bytes = 4096 preemption_threshold = 8 Predicted value: 70.2500 Surface optimum (via L-BFGS-B, linear model): task_priority_levels = 4 tick_rate_hz = 100 stack_size_bytes = 4096 preemption_threshold = 8 Predicted value: 70.2500 Model quality: Weak fit — consider adding center points or using a different design. Factor importance: 1. preemption_threshold (effect: 12.6, contribution: 50.7%) 2. tick_rate_hz (effect: -8.9, contribution: 35.6%) 3. task_priority_levels (effect: 2.4, contribution: 9.6%) 4. stack_size_bytes (effect: -1.0, contribution: 4.1%)
← Previous: BLE Mesh Topology Next: LoRaWAN Parameters →