HoopSnake
HoopSnake

Reputation: 736

Parallel Programming TPL

When you spawn multiple tasks, like so:

 for (int i = 0; i < 1000000; i++) {
        // create a new task
        tasks[i] = new Task<int>((stateObject) => {
            tls.Value = (int)stateObject;

                for (int j = 0; j < 1000; j++) {
                // update the TLS balance
                tls.Value++;
                }

            return tls.Value;
            }, account.Balance);

        tasks[i].Start();
 }

Those tasks are basically operating on a ProcessThread. So therefore we can slice 1 process thread 1,000,000 times for 1,000,000 tasks.

Is it the TPL task scheduler that looks at the OS and determines that we have 8 virtual process threads in a multicore machine, and then allocates the load of 1,000,000 tasks across these 8 virtual process threads?

Upvotes: 2

Views: 351

Answers (2)

Henk Holterman
Henk Holterman

Reputation: 273244

Roughly, your current code pushes 1000000 tasks on the ThreadPool. When thosee Tasks take some significant time you could run into problems.

In a situation like this, always use

Parallel.For(0, 1000000, ...);

and then you not only have the scheduler but more important also a partitioner helping you to distribute the load.
Not to mention it's much more readable.

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564413

Nows tasks are basically operating on a ProcessThread..so therefore we can slice 1 process thread 1000000 times for 1000000 tasks.

This is not true. A Task != a thread, and especially does not equate to a ProcessThread. Multiple tasks will get scheduled onto a single thread.

Is it the TPL task schduler that looks at the OS and determines that we have 8 virtual Process threads in a multicore machine, and so therefore allocates the load of 1000000 tasks across these 8 vgirtual process threads ?

Effectively, yes. When using the default TaskScheduler (which you're doing above), the tasks are run on ThreadPool threads. The 1000000 tasks will not create 1000000 threads (though it will use more than the 8 you mention...)

That being said, data parallelism (such as looping in a giant for loop) is typically much better handled via Parallel.For or Parallel.ForEach. The Parallel class will, internally, use a Partitioner<T> to split up the work into fewer tasks, which will give you better overall performance since it will have far less overhead. For more details, see my post on Partitioning in the TPL.

Upvotes: 6

Related Questions