Reputation: 736
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
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
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