On Wed, Dec 02, 2009 at 08:19:06AM -0500, Paul Davis
wrote:
On Wed, Dec 2, 2009 at 7:37 AM,
<fons(a)kokkinizita.net> wrote:
This change ensures that threads using the same
period
will have the same priority, even if they are not in
the same client. This is absolutely necessary in order
to make two or more such clients work together smoothly
and have 'fair' scheduling. This should become some sort
of 'standard' if more apps start using such schemes.
my understanding of SCHED_FIFO says that it doesn't really work this
way. if you want to use equal priorities to ensure fair scheduling
among RT threads, you want SCHED_RR so that the kernel scheduler can
intervene and ensure roughly equivalent scheduling. if you use
SCHED_FIFO then every thread of the same priority will run until it
voluntarily yields. is this what you mean by "fair" scheduling? it
seems to me that whether this works or not depends entirely on what
the threads are actualy doing (i.e. how long before they are
guaranteed to yield the processor).
In the general case this would be correct, SCHED_FIFO
does not in any way ensure that threads get a 'fair
share of time'. But this is not the general case.
In cases such as the one discussed, the threads are
triggered at a divisor of Jack's period rate. Each
time they get a quantum of work, perform it, and
wait for the next trigger. They do not try to run
for as long as they can.
The threads do not compete on CPU time: the assumption
is always that there is enough CPU power to perform
all the work. If this is not the case the whole thing
fails anyway.
The 'competition' is on the order in which they are
allowed to run, and for that priority is the only
criterion.
The objective of the priority scheme is to allow all
threads to meet their deadline, not to give them equal
CPU shares. They don't need equal CPU shares anyway,
in most cases the bulk of the work is done by the
lowest priority ones.
An example should make this clear. Assuming the
period size is 256, running the 'Great Hall' reverb
in jconvolver, configured for a minimum partition
size of 256 (no processing delay) will result in the
following threads:
(you can use -v to see this)
prio = 0, offs = 0, parsize = 256, npar = 3
prio = -1, offs = 768, parsize = 512, npar = 6
prio = -3, offs = 3840, parsize = 2048, npar = 6
prio = -5, offs = 16128, parsize = 8192, npar = 13
The first one is Jack's process thread, this will do the
work for 3 partitions of size 256. The second one will do
6 partitions of size 512, it will be triggered every two
periods. The next one runs every 8 Jack periods, the last
one every 32.
The last three are required to have completed their work
when the next trigger arrives. Their output is actually
only required later, 3 periods after the start for the
size 512, 15 periods for the size 2048, and 31 for the
last. This gives the whole system some robustness it
would not have if everything was planned 'just in time'.
Note that the extra margin is small for small partition
sizes and quite big for the larger ones.
Now if the same reverb is configured to use a minumum
period size of 4096 (because the user can tolerate the
delay and wants less CPU load) this would look different:
prio = -4, offs = 0, parsize = 4096, npar = 2
prio = -5, offs = 8192, parsize = 8192, npar = 14
As you can see the priorities match the partition size.
In this case no work is done in Jack's thread.
Now assume that I would use the scheme of version 1.0.0.
Then the priorities would be
-1 512
-2 2048
-3 8192
and
-1 4096
-2 8192
respectively. This would mean that the size 4096 thread
of the second instance would have the same priority as
the size 512 thread of the first. The time required for
the size 4096 calculations could easily be longer than
the period of of the size 256 thread. This would result
in the size 256 thread being late every time it has to
wait for the other to complete, which could happen every
16 periods.
Matching priorities to period size removes this problem,
and ensure that the most urgent work will always be done
first.
Does the "partition" parameter in the conf file affect this?
On the reverbs I've been using successfully with freewheeling mode, the
"partition" is set to 2048, which is very high compared to the setting in the
sample reverbs tthat come with jconv.
-ken