Skip to content

Commit 2c9e936

Browse files
authored
Improve scheduling configuration of examples_rclcpp_cbg_executor package (#331)
* Reduced the OS-specific priority of the high prio Executor thread on Linux and QNX. Chose the configuration to be below typical threaded interrupt handlers. Signed-off-by: Ralph Lange <[email protected]>
1 parent 0088f1a commit 2c9e936

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

rclcpp/executors/cbg_executor/README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,18 @@ ros2 run examples_rclcpp_cbg_executor ping_pong
2929
Example of a typical output - note the zero pongs received on the low prio path:
3030

3131
```
32-
[INFO] [..] [pong_node]: Running experiment from now on for 10s ...
33-
[INFO] [..] [ping_node]: Both paths: Sent out 982 of configured 1000 pings, i.e. 98%.
34-
[INFO] [..] [ping_node]: High prio path: Received 980 pongs, i.e. for 99% of the pings.
35-
[INFO] [..] [ping_node]: High prio path: Average RTT is 17.2ms.
32+
[INFO] [..] [pong_node]: Running experiment from now on for 10 seconds ...
33+
[INFO] [..] [ping_node]: Both paths: Sent out 953 of configured 1000 pings, i.e. 95%.
34+
[INFO] [..] [ping_node]: High prio path: Received 951 pongs, i.e. for 99% of the pings.
35+
[INFO] [..] [ping_node]: High prio path: Average RTT is 14.0ms.
36+
[INFO] [..] [ping_node]: High prio path: Jitter of RTT is 7.460ms.
3637
[INFO] [..] [ping_node]: Low prio path: Received 0 pongs, i.e. for 0% of the pings.
37-
[INFO] [..] [pong_node]: High priority executor thread ran for 9995ms.
38+
[INFO] [..] [pong_node]: High priority executor thread ran for 9542ms.
3839
[INFO] [..] [pong_node]: Low priority executor thread ran for 0ms.
3940
```
4041

42+
Note: On Linux, the two Executor threads, which are both scheduled under `SCHED_FIFO`, can consume only 95% of the CPU time due to [RT throttling](https://wiki.linuxfoundation.org/realtime/documentation/technical_basics/sched_rt_throttling).
43+
4144
Running the two nodes in separate processes:
4245

4346
```bash
@@ -74,11 +77,13 @@ With these values, about (0.033s - 0.025s) / 0.010s = 80% of the ping messages o
7477

7578
```
7679
...
77-
[INFO] [..] [ping_node]: Both paths: Sent out 303 of configured 303 pings, i.e. 100%.
78-
[INFO] [..] [ping_node]: High prio path: Received 302 pongs, i.e. for 99% of the pings.
79-
[INFO] [..] [ping_node]: High prio path: Average RTT is 25.2ms.
80-
[INFO] [..] [ping_node]: Low prio path: Received 231 pongs, i.e. for 76% of the pings.
81-
[INFO] [..] [ping_node]: Low prio path: Average RTT is 196.1ms.
80+
[INFO] [..] [ping_node]: Both paths: Sent out 294 of configured 303 pings, i.e. 97%.
81+
[INFO] [..] [ping_node]: High prio path: Received 293 pongs, i.e. for 99% of the pings.
82+
[INFO] [..] [ping_node]: High prio path: Average RTT is 26.2ms.
83+
[INFO] [..] [ping_node]: High prio path: Jitter of RTT is 7.654ms.
84+
[INFO] [..] [ping_node]: Low prio path: Received 216 pongs, i.e. for 73% of the pings.
85+
[INFO] [..] [ping_node]: Low prio path: Average RTT is 202.5ms.
86+
[INFO] [..] [ping_node]: Low prio path: Jitter of RTT is 36.301ms.
8287
...
8388
```
8489

rclcpp/executors/cbg_executor/src/examples_rclcpp_cbg_executor/utilities.hpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,12 @@ bool configure_native_thread(T native_handle, ThreadPriority priority, int cpu_i
113113
int policy;
114114
success &= (pthread_getschedparam(native_handle, &policy, &params) == 0);
115115
if (priority == ThreadPriority::HIGH) {
116-
params.sched_priority = sched_get_priority_max(SCHED_FIFO);
116+
// Choose a priority value slighly below the middle.
117+
params.sched_priority =
118+
(sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2 - 1;
117119
} else {
120+
// Choose the lowest priority in SCHED_FIFO. This might still be higher than
121+
// the priority of the DDS threads, which are not changed here.
118122
params.sched_priority = sched_get_priority_min(SCHED_FIFO);
119123
}
120124
success &= (pthread_setschedparam(native_handle, SCHED_FIFO, &params) == 0);
@@ -144,8 +148,21 @@ bool configure_native_thread(T native_handle, ThreadPriority priority, int cpu_i
144148
int policy;
145149
success &= (pthread_getschedparam(native_handle, &policy, &params) == 0);
146150
if (priority == ThreadPriority::HIGH) {
147-
params.sched_priority = sched_get_priority_max(SCHED_FIFO);
151+
// Should be a value of 49 on standard Linux platforms, which is just below
152+
// the default priority of 50 for threaded interrupt handling.
153+
params.sched_priority =
154+
(sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2 - 1;
148155
} else {
156+
// Choose the lowest priority under SCHED_FIFO. This will still be higher than
157+
// the priority of the DDS threads, which are not changed here. Normally
158+
// the DDS threads will be executed under SCHED_OTHER at nice value 0.
159+
// Note that changing the priority below the default user-space priority requires
160+
// increasing the nice level. This has not been implemented here for two reasons:
161+
// First, the Linux API does not allow to get the Linux-specific thread ID (TID)
162+
// for changing the nice value from an arbitrary pthread_t pointer, but only from the
163+
// current thread by gettid(). Second, a low prio Executor thread under SCHED_OTHER
164+
// would always get 50 ms per second due to RT throttling if not configured
165+
// otherwise. This would be difficult to explain in a demo.
149166
params.sched_priority = sched_get_priority_min(SCHED_FIFO);
150167
}
151168
success &= (pthread_setschedparam(native_handle, SCHED_FIFO, &params) == 0);

0 commit comments

Comments
 (0)