NET 4.0 多任务编程 之四 Parallel初体验

在.NET Framework 4.0中,在库的层次上,微软提供了大量的新内容来帮助程序员完成应用程序的并行化,其中包括Parallel LINQ,Task Parallel Library和Coordination Data Structures,这些新的类型和类,在System.Threading,System.Threading.Tasks,System.Linq和System.Collections.Concurrent这些名字空间中提供。通过这些新的类型和类,开发人员将无需面对如今复杂的多线程开发模式,而可以直接使用.NET Framework,更加高效简便地开发支持并行计算的应用程序,从而更加充分地利用多核CPU的优势,随着计算核心或者处理器的增加,以提升应用程序的性能。

dennis_zane同学在其《几行代码解决淘宝面试题 之Clojure版》一文中提到:为了多核,你要将list拆分下,每个子list并发去计算和,然后综合这些结果求出最终的和...话虽不错,未免失之简单,很多时候根据 source list 的不同类型,以及每次循环时所需要调用的处理方法执行时间的长短不同,要想达到最高性能,则必须对 Parallel相关特性进行详细的了解。


这里我们就先来介绍一下最简单最常用的TPL。




而在.NET Framework中,Task Parallel Library (TPL)是其Parallel Extensions中一个重要组成部分,它提供了一种简便的多线程开发方式,通过它所提供的类或者函数,可以让程序员轻松地实现并行计算。其中,最简单的就是它的Parallel类

现在.NET 4.0 有了Parallel.ForEach(), Parallel.For(),PLINQ 等非常有用的并行相关的支持。但是,并不是简单的利用这些方法的简单形式就可以了。

大致上,.NET中的Parallel.ForEach 对 source list 有以下几种拆分模式:
  • Range 拆分。适用于原始输入是 Array 或 IList 的情况,这时候,list.Count 确定。所以比较容易根据 source list 的长度,拆分为对应的几个 Range 对象,一次分配好任务的拆分方式,而且因为范围互相不冲突,多个子任务之间不需要线程同步的开销。
  • Trunk 拆分。预先创建好几个工作者 trunk. 然后依次扫描 source,这些 chunk 轮流去获取 element 进行处理。一般每个 chunk 一次获取很少的元素,比如1个。对于不确定长度的 source 可能比较有用,但有线程同步的开销。这个可能会适用于不定长度的 source list. 比如,你自己定义一个返回 IEnumerable<T> 的 generator 方法,在里面根据具体的逻辑用 yield return 返回一系列元素,这个可能就比较复杂。
  • 自定义的 partitioner. 假设在自己对 source class 的内部构造比较了解的情况下,则有可能写出比系统的 partitioner 性能更高的自定义 partitioner. 但是,需要仔细阅读并了解 MSDN 的范例以创建 custom partitioner.


你可能感兴趣的:(多线程,编程,.net,面试,LINQ)