前 言 在2007年,Microsoft发布了适用于。NET Framework的Parallel Extensions的第一个 Community Technology Preview(CTP)。老。NET Framework中的多线程编程模型太复杂,属于重量级模型,已经不适合于正在流行的多核和众核CPU。从1997年开始,我就一直在研究并行编程、多处理器和多核处理器,所以我情不自禁地安装了第一个版本的CTP进行试用。很明显,这个CTP充分展现了未来C#版本中激动人心的并行编程方式。 Visual Studio 2010随着。NET Framework第4版一起发布,这是第一个包含了Parallel Extensions(并行扩展)的发行版。通过C# 4和。NET Framework 4,您可以通过一个全新的基于任务的编程模型来描述并行。编写充分利用多核处理器能力的代码变得更加容易。现在,您可以编写能够随着可用内核增长而扩展的代码,而不用费力地去处理复杂的托管线程。您可以编写运行任务的代码,而CLR(Common Language Runtime,公共语言运行时)会自动注入必要的线程。现在还能很容易地运行充分利用多核处理能力的数据并行算法。 在撰写本书时,多核微处理器已经无处不在了。服务器、桌面计算机、笔记本电脑、上网本、移动因特网设备(MID)、平板电脑甚至连智能手机都在使用多核微处理器了。每个微处理器的平均内核数在未来会不断增长。您肯定不想错过将这些多核处理能力转换为应用程序性能的机会吧? 并行编程必然会成为您在现代硬件上高效开发C#应用程序的技能的一部分。在Visual Studio 2010正式发布之前,我花了3年多时间使用各种不同版本的Parallel Extensions。我很享受用C#语言开发并行应用程序的乐趣,并且我尽可能地在这本书中讲解了最常见的情形。 Visual Studio 2010带有一个专为并行开发人员设计的IDE,而C#也非常适合这个新的基于任务的编程模型。 本书读者对象 本书旨在帮助有经验的C#开发人员能够利用。NET Framework 4中引入的Parallel Extensions,将现代微处理器中的多核处理能力转换为应用程序的性能。无论您是刚刚开始从老的多线程模型开始转换,还是已经有过一些编写并发和并行代码的经验,而且想要获得更深入的理解,这本书都能够为您提供您所需要的最常用的并行编程技能和概念。 尽管这本书提供了大量并行编程概念,但C#和。NET Framework 4提供的并行编程能力太多太复杂,因此不可能在一本书中涵盖所有内容。这本书的目的是为那些需要充分利用多核和众核体系结构处理能力的C#开发人员提供与重要技术相关的知识。本书为有经验的C#开发人员提供了充裕的内容,从而让他们能够在很多高层次的并行领域中游刃有余。本书涵盖了新的基于任务的编程模型。对分布式并行化和底层并发编程技术感兴趣的开发人员也可以选择本书作为这些领域专着的补充,从而完善自己的知识。 本书提供的一些背景信息对于避免常见的并行编程陷阱非常重要。因此,在阅读本书的时候最好不要跳过章节。此外,在没有读完某一章的时候,不要将这一章中所展示的代码当作是最佳实践。随着每一章对Parallel Extensions介绍的深入,会通过更简单更高效的编程技术对这些示例进行改进。 本书假设您是一位富有经验的C#和。NET Framework 4开发人员,并且正在关注并行编程相关的主题。如果您缺少以下方面的经验:高级面向对象编程技术、列表、数组、闭包、委托、lambda表达式、LINQ、类型转换以及基本的调试技术,那么您可能需要一些额外的学习才能完全理解本书中列举的示例。 本书涵盖的内容 本书涵盖了以下关键技术和概念: ●现代多核和众核共享内存体系结构 ●通过Task Parallel Library(TPL)、C#和。NET Framework进行高层的基于任务的程序设计 ●Parallel Language Integrated Query(PLINQ) ●用于基于任务的编程的大部分常见的协调数据结构和同步原语 ●Visual Studio 2010中与并行编程相关的调试和性能剖析能力 ●在真实世界的应用程序中能够让您主宰多核编程的额外的库、工具和其他库 本书没有包含老的多线程编程模型和分布式并行的内容。 本书结构 某些主题的掌握非常关键。如果您之前没有使用过。NET Framework 4引入的新的基于任务的编程模型,那么您应该逐章阅读本书。每一章在编写的时候都假定您已经阅读了前一章。然而,如果您之前使用过TPL和PLINQ,那么您应该可以阅读并理解与并行调试和调优相关的章节。 本书分为以下11章和3个附录: 第1章“基于任务的程序设计”--探讨新的基于任务的编程模型,通过这个新的模型可以在。NET Framework 4应用程序中引入并行性。并行对于发挥现代多核和众核体系结构的威力来说非常关键。这一章讲解了新的轻量级并发模型以及和并发与并行相关的重要概念。这一章的内容非常重要,因为这一章包含了后面10章和附录所需要的必备背景知识。 第2章“命令式数据并行”--开始学习C# 4和。NET Framework 4中引入的新的编程模型,并且将这些模型应用于纯数据并行问题。这一章讲解了一些新的类、结构体和枚举,通过这些结构可以处理数据并行的情形。运行这些示例,可以更好地理解性能提升。 第3章“命令式任务并行”--开始使用新的Task实例,以简单的代码解决命令式任务并行的问题和复杂的算法。这一章讲解了一些新的类、结构体和枚举,通过这些结构可以处理任务并行的情形。通过新的基于任务的模型所提供的基本功能和复杂功能来并行地实现现有算法。使用任务而不是线程来创建并行代码。 第4章“并发集合”--基于任务的程序设计、命令式数据并行和任务并行都要求使用能够支持并发更新的数组、列表和集合。通过使用新的并发集合,可以简化代码,并且获得最佳性能。这一章讲解了一些新的类和新的接口,通过这些类和接口可以在多个任务中使用共享的并发集合。这一章讲解了如何创建不同的顺序模式和结构的并行代码在列表中添加、删除以及更新不同类型的值。 第5章“协调数据结构”--同步由不同的并发任务所执行的工作。这一章讲解了一些经典的同步原语以及。NET Framework 4引入的轻量级协调数据结构。学习不同的替换方案是非常重要的,这样就可以为每种需要在多个任务之间进行通信和同步的并发情形选择最合适的方案。这是本书中最复杂的一章,也是最重要的章节之一。在编写复杂的并行算法之前,一定要首先阅读这一章。 第6章“PLINQ:声明式数据并行”--通过Parallel Language Integrated Query(PLINQ)及其聚合函数实现声明式数据并行。通过PLINQ,可以简化混合运行任务和数据分解的代码。您还可以执行经典的并行Map Reduce算法。这一章结合了之前章节所介绍的很多主题,并且讲解了如何将一个LINQ查询转换为PLINQ查询。此外,这一章还讲解了如何根据各种不同的情形对PLINQ的并行执行进行调优。 第7章“Visual Studio 2010的任务调试能力”--充分利用 Visual Studio 2010中引入的任务调试功能。这一章讲解了新窗口如何显示一些重要的信息,这些信息包括任务、任务和源代码之间的关系以及分配给任务的支持任务的执行的线程。在利用。NET Framework 4编写并行代码的时候,通过这些新的窗口可以检测并解决潜在的故障。 第8章“线程池”--理解使用任务以及直接请求工作项在线程池的线程中运行之间的区别。如果使用了一个线程池,那么就可以充分利用新的增强功能,将代码转移到基于任务的编程模型。这一章介绍了。NET Framework 4中CLR线程池引擎的变化,并提供了一个自定义任务调度器的示例。 第9章“异步编程模型”--将现有异步编程模型和任务结合起来。这一章提供了真实的案例,讲解了如何充分利用任务和延续的简洁性来执行与现有异步编程模型有关的异步任务。此外,这一章还讲解了一个与并发编程有关的最复杂的问题:从不同的任务和线程中对用户界面(UI)进行更新。这一章介绍了在Windows Form应用程序以及WPF应用程序中更新UI的模式。 第10章“并行测试和调优”--介绍了Visual Studio 2010 Premium版和Ultimate版中引入的并发剖析功能。学习与。NET Framework 4并行代码有关的常见且容易判断的问题是非常重要的。这一章讲解了一些不同的技术,通过这些技术可以创建并运行并行测试和基准评分。这一章还讲解了如何根据每一个性能剖析会话的结果对现有的应用程序进行重构。 第11章“向量化、SIMD指令以及其他并行库”--充分利用现代硬件所提供的其他与并行化相关的能力。。NET Framework 4不支持直接使用SIMD和向量化。但是,大部分现代微处理器都提供了这些强大的附加指令。因此,您可以使用经过优化的函数库,这些函数库充分利用了这些指令带来的性能提升。这一章讲解了如何将Intel Math Kernel Library整合进C#编写的基于任务的代码中。此外,这一章还讲解了如何使用Intel Integrated Performance Primitives对临界区进行优化。 附录A“。NET 4中与并行相关的类图”--这个附录包含了一些类、接口、结构体、委托、枚举和异常的示意图,这些结构通过新的轻量级并发模型和底层线程模型对并行化提供了支持。该附录中还包含了对本书章节的引用,通过引用可以找到详细解释这些图的正文内容。 附录B“并发UML模型”--这个附录列举了一些示例,这些示例讲解了如何使用UML模型来展示并发和并行的设计和代码。通过添加一些简单的标准化的视觉元素,您就可以对经典的模型进行扩充。 附录C“Parallel Extensions Extras”--Parallel Extensions Extras是一个补充性质的项目,并不是。NET Framework 4类库的一部分。但是这个项目是由Microsoft开发的,并且是。NET Framework 4并行编程范例的一部分。这个附录包含了Parallel Extensions Extras中的类和结构体的图示以及简单介绍。 阅读本书的先决条件 为了能够最大限度地发挥这本书的作用,您需要Visual Studio 2010 Premium版或Ultimate版,这两个版本的Visual Studio包含了。NET Framework 4以及并发性能剖析的功能。您也可以使用Visual Studio 2010 Standard版,但是这个版本并没有包含并发性能剖析的功能。您不应该使用Visual C# 2010 Express版,因为这个版本并没有提供对基于任务的程序设计进行调试所需要的调试窗口。 此外,您的开发计算机至少需要具有2个物理内核,这样您才能理解本书中所展示的示例。然而,如果您还需要测试可扩展性,那么最好要有3个以上的物理内核。 Windows 7和Windows 2008 R2在调度器上做了显着的增强,提升了多核和众核系统的可扩展性。本书描述的应用程序应该运行在这些版本的Windows系统上。如果您使用的是更早的Windows版本,那么测试结果就可能会有所不同。