Pregunta

I'm constructing a pipeline using TPL Dataflow. Say I have a pipeline that consists of four TransformBlocks

GetDataFromDatabase
ProcessData1
ProcessData2
SendDataToRestService

Each of these may (probably will) be a long running operation. GetDataFromDatabase will probably mostly be waiting for the database to respond, SendDataToRestService be waiting for the service to response. ProcessData 1 and 2 will be long running local, CPU intense processes.

Now, my intention was to set maxdegreeofparalellism on each of my blocks to the number of cores on the machine (which will probably be 4).

But it occurs to me that that means that it will do 4 GetDataFromDatabases at once, and 4 ProcessData1 at once, and 4 ProcessData2 at once, and 4 SendDataToRestService at once. Which would mean I could potentially have 16 threads running at the same time. Add to this that I actually have 3 different flows doing similar stuff at the same time.

QUESTION: What's the best approach to this, so that I get the best performance? From what I've read, if I try to do too much, I can actually slow down performance due to context switching. Is there a best approach, or is it "suck it and see"?

¿Fue útil?

Solución

First, as @usr suggested, your case fits a single ActionBlock. The point of linking multiple blocks is to compose different types of blocks with different configurations. For example if you had one step with MaxDegreeOfParallelism of 1, and another with 10.

Second, MaxDegreeOfParallelism sets the maximum, which means that the TPL can choose any number in that range according to the availability of resources. So I wouldn't fear setting the maximum value for all those blocks, and if TPL decides it's better to use less threads, it will.

From How to: Specify the Degree of Parallelism in a Dataflow Block

Because the MaxDegreeOfParallelism property represents the maximum degree of parallelism, the dataflow block might execute with a lesser degree of parallelism than you specify. The dataflow block can use a lesser degree of parallelism to meet its functional requirements or to account for a lack of available system resources. A dataflow block never chooses a greater degree of parallelism than you specify.

Otros consejos

I think what would make sense here would be to combine the two CPU-bound blocks into one. That way, you can tune the blocks with different characteristics separately.

If that wasn't possible (that could happen for example if the CPU-bound blocks weren't next to each other in the pipeline), then it would most likely still be okay to set MaxDegreeOfParallelism of each CPU-bound block to ProcessorCount. The thread pool is smart and won't use too many threads, unless it thinks it would be advantageous. Though I think using blocking IO code in the other blocks (or other parts of the program) could confuse this, so I would suggest using asynchronous IO.

In any case, using slightly more threads than necessary most likely won't be a big problem. If you really need to fix this anyway, you could use a custom TaskScheduler that limits the number of threads and set that as the DataflowBlockOptions.TaskScheduler for the CPU-bound blocks.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top