There is something else about pipelines, I am not sure how it works.
Let's say, the very first stage of a pipeline is serial, but it can process tokens very quickly. The other stages are parallel and slow. Once the maximum number of tokens reached, what happens to the worker thread which is serving the first filter? Will it wait until more tokens are needed or will it switch to another filter? In my case it is important, that the thread won't wait and switch to another filter immediately. Is the pipeline suitable for me?
The way the pipeline implementation works is that a thread carries a token as far as possible through the pipeilne, until it reaches a serial stage that it must wait on. At that point the thread parks its current token and may be reassigned to another token, if there another token or a new token can be created without exceeding the token limit. So in the case where the parallel stage is the bottleneck, it's possible that the code might not even reach the maximum token limit. For example, in the ideal case where no thread has to wait at a serial stage, the number of tokens will be the number of threads. Of course in practice, even if the parallel stages are the bottleneck, there will likely be occasional waiting because two threads reach a serial stage at the same time or out of order.
"Of course in practice, even if the parallel stages are the bottleneck, there will likely be occasional waiting because two threads reach a serial stage at the same time or out of order."
I think it's useful to point out that this does not apply to the situation in #2, but only if the slow parallel stages are somewhere between two ordered serial stages.
It may not be optimal in my case. I forgot to mention, that the first filter has a fairly large non constant state. The state changes every time the filter is used. It is better if a thread sticks to the first stage for a while in order to create a few tokens for itself and other threads. I want to merge all filter into one task and use task group instead of pipeline.
Here is the plan:
(2) Start scheduling new tasks with task_group::run method as soon as enough tokens are available. It would be the slow and parallel stage 2.
(3) Once a curtain number of task are enqueued, schedule a task with task_group::run_and_wait method.
(4) Repeat steps 1-3 until no more work left.
As I understand, TBB doesn't preempt threads, so that the main thread can produce tokens at full speed until it reaches step 3 and calls run_and_wait. Is it how the task group works or there is a possibility that the main thread gets preempted before reaching the step 3?