简体   繁体   中英

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?

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM