简体   繁体   English

并行编程TPL

[英]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. 这些任务基本上是在ProcessThread上运行的。 So therefore we can slice 1 process thread 1,000,000 times for 1,000,000 tasks. 因此,我们可以为1,000,000个任务将1个进程线程切片1,000,000次。

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? TPL任务调度程序是否可以查看操作系统并确定我们在多核计算机上具有8个虚拟进程线程,然后在这8个虚拟进程线程之间分配1,000,000个任务的负载?

Nows tasks are basically operating on a ProcessThread..so therefore we can slice 1 process thread 1000000 times for 1000000 tasks. 现在,任务基本上在ProcessThread..so上运行,因此,我们可以将1个进程线程切片1000000次,以执行1000000个任务。

This is not true. 这不是真的。 A Task != a thread, and especially does not equate to a ProcessThread . Task!=线程,特别是不等于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 ? 是TPL任务调度程序查看操作系统并确定多核计算机中有8个虚拟进程线程,因此在这8个虚拟进程线程之间分配了1000000个任务的负载吗?

Effectively, yes. 实际上,是的。 When using the default TaskScheduler (which you're doing above), the tasks are run on ThreadPool threads. 使用默认的TaskScheduler(如上操作)时,任务在ThreadPool线程上运行。 The 1000000 tasks will not create 1000000 threads (though it will use more than the 8 you mention...) 1000000个任务将不会创建1000000个线程(尽管它将使用的线程数超过您提到的8个...)

That being said, data parallelism (such as looping in a giant for loop) is typically much better handled via Parallel.For or Parallel.ForEach . 话虽这么说,通常通过Parallel.ForParallel.ForEach处理数据并行性(例如,在巨型for循环中循环)要好得多。 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. 在内部,Parallel类将使用Partitioner<T>将工作分解为更少的任务,这将给您带来更好的总体性能,因为它的开销要少得多。 For more details, see my post on Partitioning in the TPL . 有关更多详细信息,请参阅我在TPL中进行分区的文章。

Roughly, your current code pushes 1000000 tasks on the ThreadPool. 大致来说,您当前的代码在ThreadPool上推送了1000000个任务。 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. 更不用说它更具可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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