技术开发 频道

初探.NET4和VS 2010中的多核利用

    【IT168 技术文档】如果你想利用多核机器的强大计算能力,你需要使用PLINQ(并行LINQ),任务并行库(Task Parallel Library,TPL)和Visual Studio2010中的新功能创建应用程序。

  以前,如果你创建的多线程应用程序有BUG,那要跟踪起来是很麻烦的,但现在情况完全变了,感谢微软为我们带来了Microsoft Parallel Extensions for .NET(.NET并行扩展),它在.NET框架线程模型上提供了一个抽象层。

  并行扩展遵循微软在COM应用程序中建立的事务管理和在数据访问领域建立的实体框架和LINQ模型,它试图通过给.NET框架中的复杂过程建立高级支持,以便将先进的技术带给大众,随着多核处理器的普及,开发人员渴望他们的应用程序可以利用所有处理器核心的计算能力。

  你可以通过并行LINQ(PLINQ)和任务并行库(Task Parallel Library,TPL)使用并行扩展的功能,它们都允许你为单核和多核计算机写一套代码,依靠.NET框架,最大限度利用代码执行平台的计算能力,并防止自行创建多线程应用程序时常见的陷阱。

  PLINQ扩展了LINQ查询,它将单个查询分解成多个并行运行的子查询,TPL允许你创建并行运行的循环,而不是一个接一个地运行,虽然PLINQ的声明语法使创建并行进程更加简单,但一般情况下,面向TPL的操作比PLINQ查询更轻量级。

  许多时候,选择TPL还是PLINQ只是一种生活方式,如果喜欢并行循环,而不是并行查询,那么设计一个TPL解决方案比设计一个PLINQ解决方案更容易。

  PLINQ简介

  对于商业应用程序,只要LINQ查询涉及到多个子查询时,PLINQ就像金子一样发光,如果你要连接本地数据库某张表中的行和另一个远程数据库某张表中的行,PLINQ将非常有用,在这种情况下,LINQ必须在每个数据源上独立运行子查询,然后调和结果,PLINQ将会把这些子查询分配给多个处理器核心,这些子查询就可以同时执行。实际上,你使用的处理器周期不是少了,而是更多了,当然好处就是你可以更早得到结果,请阅读“并行处理不会让你的应用程序变得更快”了解更多关于多线程应用程序的行为。

  并行处理不会让你的应用程序变得更快

  关于多线程应用程序最常见的一个误解是,应用程序线程越多,运行速度就越快,多启动一个线程并不会导致Windows给你的应用程序更多的处理周期,它只是把这些周期划分给更多线程了,实际上,在单处理器计算机上,开启多线程只会让你的应用程序变得更慢。

  多线程只是让你的应用程序响应更快,但它仍然要等待其它阻塞任务完成先,不过在等待期间,你可以利用多线程应用程序的特点让其它线程做一些别的事情。在单核机器上,如果线程未被阻塞,多个线程只能相互争夺有限的处理周期。

  多核处理器改变了这种状况,在多核环境中,你可以让Windows给你的应用程序分配更多的处理周期,你不需要阻塞线程,所有线程都在它们自己的核心上执行。并行扩展提供了编程结构,允许你告诉.NET框架应用程序那些部分可以并行执行。

  即使在多核机器上,PLINQ也并不总是并行的查询,有两个原因,一是你的应用程序并行运行不会总是更快,第二个原因是,即使你有一个抽象层管理你的线程,在并行处理时总会出现脚步不一致的情况,PLINQ会检查一些不安全的条件,如果检测到就不会进行并行查询。我会指出PLINQ不会检查的问题和条件,但使用PLINQ出了问题只有你自己负责处理。

  处理PLINQ

  调用PLINQ很简单,只需要在你的数据源中添加AsParallel扩展,下面是一个从本地Northwind数据库连接远程Northwind数据库,根据客户(customer)信息查询订单(Orders)的示例:

Dim ords As System.Linq.ParallelQuery(Of ParallelExtensions.Order)  ords = From c In le.Customers.AsParallel Join o In re.Orders.AsParallel            
On c.CustomerID Equals o.CustomerID        
Where c.CustomerID
= "ALFKI"        
Select o

 

  因为两个数据源都标记了AsParallel(在连接时,如果一个数据源使用了AsParallel,另一个也必须使用),因此将会使用PLINQ。

  和普通的LINQ查询一样,PLINQ查询使用延迟处理,即等到你要真正使用数据时,它才会开始检索,这意味着即使LINQ查询声明了是并行的,在你要处理结果前不会发生并行处理,除非使用下面这样的代码块:

For Each ord As Order In ords    
ord.RequiredDate.Value.AddDays(
2)  
Next

 

  在后台,PLINQ将使用一个线程执行For …Each循环中的代码,而其它线程可能被用来执行子查询,最大可以使用64个线程,请阅读“并行控制”材料了解这种行为的更多信息。

0
相关文章