03-01-2021, 03:53 AM
Once again I'll preface my post with "I'm not here to argue for or against tweaks" but this time I want to clear up an apparent misunderstanding concerning the Linux concepts of isolcpus and taskset.
isolcpus
This is a kernel parameter and this is the definition of it from kernel.org/doc/v5.4/admin-guide/kernel-parameters.html
Oops. Deprecated? Yup, and has been for some time. However, as can be seen in the syntax definition, the flag-list is optional and the default results in the same behavior as in older kernels, e.g., "Isolate from the general SMP balancing and scheduling algorithms". Hence it still works, at least for now.
So, when one uses isolcpus=2,3 then only cpus 0 and 1 (assuming the RPi model in question has 4 cpus) can be assigned processes in a normal way by moOde/RaspiOS. On the other hand, cpus 2 and 3 will be used if and only if processes are manually assigned to them.
It appears to me in reading this forum thread that the first part of this concept is well understood but that the implication of being isolated from the balancing and scheduling algorithms is not as well understood.
taskset
From the man page for this command (reformatted to fix this forum page)
As noted by another in a previous post, using this command is equivalent to specifying CPUAffinity in the service file. Either way, there is a not-subtle difference between using a cpu range here when the isolcpus= parameter is not used and when it is used.
Another practical implication is that all the remaining processes are thrown onto cpu 0 and cpu 1, essentially doubling their loads. On a typical RPi4B moOde installation, I've found that each of the 4 cpus is running approximately 35 processes, albeit not necessarily all active at once. With 2 cpus isolated, on the other hand, the remaining two cpus are each running approximately 70 processes. Whether this introduces new performance issues depends on the overall usage.
Bottom line:
If you must isolate a process using this deprecated technique, then I suggest you try using isolcpus=3 and taskset=3. If you want to isolate two processes, each to its own cpu, then try using isolcpus=2,3 while using taskset=2 for one process and taskset=3 for the other.
Regards,
Kent
PS - the purpose of this post is only to clarify Linux. I don't wish to discuss fine tuning either the deprecated technique or the cpusets alternative. Consult your favorite search engine.
isolcpus
This is a kernel parameter and this is the definition of it from kernel.org/doc/v5.4/admin-guide/kernel-parameters.html
Code:
isolcpus= [KNL,SMP,ISOL] Isolate a given set of CPUs from disturbance.
[Deprecated - use cpusets instead]
Format: [flag-list,]<cpu-list>
Specify one or more CPUs to isolate from disturbances
specified in the flag list (default: domain):
nohz
Disable the tick when a single task runs.
A residual 1Hz tick is offloaded to workqueues, which you
need to affine to housekeeping through the global
workqueue's affinity configured via the
/sys/devices/virtual/workqueue/cpumask sysfs file, or
by using the 'domain' flag described below.
NOTE: by default the global workqueue runs on all CPUs,
so to protect individual CPUs the 'cpumask' file has to
be configured manually after bootup.
domain
Isolate from the general SMP balancing and scheduling
algorithms. Note that performing domain isolation this way
is irreversible: it's not possible to bring back a CPU to
the domains once isolated through isolcpus. It's strongly
advised to use cpusets instead to disable scheduler load
balancing through the "cpuset.sched_load_balance" file.
It offers a much more flexible interface where CPUs can
move in and out of an isolated set anytime.
You can move a process onto or off an "isolated" CPU via
the CPU affinity syscalls or cpuset.
<cpu number> begins at 0 and the maximum value is
"number of CPUs in system - 1".
The format of <cpu-list> is described above.
Oops. Deprecated? Yup, and has been for some time. However, as can be seen in the syntax definition, the flag-list is optional and the default results in the same behavior as in older kernels, e.g., "Isolate from the general SMP balancing and scheduling algorithms". Hence it still works, at least for now.
So, when one uses isolcpus=2,3 then only cpus 0 and 1 (assuming the RPi model in question has 4 cpus) can be assigned processes in a normal way by moOde/RaspiOS. On the other hand, cpus 2 and 3 will be used if and only if processes are manually assigned to them.
It appears to me in reading this forum thread that the first part of this concept is well understood but that the implication of being isolated from the balancing and scheduling algorithms is not as well understood.
taskset
From the man page for this command (reformatted to fix this forum page)
Code:
DESCRIPTION
taskset is used to set or retrieve the CPU affinity of a running process given its
pid, or to launch a new command with a given CPU affinity. CPU affinity is a
scheduler property that "bonds" a process to a given set of CPUs on the system.
The Linux scheduler will honor the given CPU affinity and the process will not
run on any other CPUs. Note that the Linux scheduler also supports natural
CPU affinity: the scheduler attempts to keep processes on the same CPU as long as
practical for performance reasons. Therefore, forcing a specific CPU affinity is
useful only in certain applications.
As noted by another in a previous post, using this command is equivalent to specifying CPUAffinity in the service file. Either way, there is a not-subtle difference between using a cpu range here when the isolcpus= parameter is not used and when it is used.
- not used: The scheduler will honor the taskset cpu range. Suppose taskset=2,3. Then the specified process (and all the threads it may spawn) will only ever run on cpu 2 or cpu 3. If more than one process has the same assigned cpu range, then the scheduler/balancer will distribute them across the range as their algorithms dictate.
- used: Suppose, again, taskset=2,3 but this time isolcpus=2,3 is also used. Then the specified process (and all the threads it may spawn) will only ever run on cpu 2. If more than one process has the same assigned cpu range, then they will all only ever run on cpu 2. Remember, these cpus have been isolated so the scheduler/balancer algorithms never see how they are being used or not used.
Another practical implication is that all the remaining processes are thrown onto cpu 0 and cpu 1, essentially doubling their loads. On a typical RPi4B moOde installation, I've found that each of the 4 cpus is running approximately 35 processes, albeit not necessarily all active at once. With 2 cpus isolated, on the other hand, the remaining two cpus are each running approximately 70 processes. Whether this introduces new performance issues depends on the overall usage.
Bottom line:
If you must isolate a process using this deprecated technique, then I suggest you try using isolcpus=3 and taskset=3. If you want to isolate two processes, each to its own cpu, then try using isolcpus=2,3 while using taskset=2 for one process and taskset=3 for the other.
Regards,
Kent
PS - the purpose of this post is only to clarify Linux. I don't wish to discuss fine tuning either the deprecated technique or the cpusets alternative. Consult your favorite search engine.