并发编程中的重重量级模型和轻量级模型

并发编程中的重重量级模型和轻量级模型

 

使用轻量级并发开发

        不管是Amdahl定律还是Gustafson的定律都没有考虑引入并发需要付出的额外开销。同时也没有考虑那些可以将顺序代码转变成可以利用并行优势的算法的设计模式。重要的是减少程序中必须执行的顺序代码,改善对并行执行单元的利用。

        以前的.NET 版本,如果你想在一个进程内并行执行C#应用程序,你必须创建和管理多线程(软件线程)。所以,你必须编写复杂的多线程代码。分解算法到多个线程上,协调不同的代码单元,在它们之间共享信息,并且收集执行结果确确实实是一件复杂的编程工作。随着逻辑核心的增多,情况变得甚至更糟了,因为你需要更多的线程来获取更好的可伸缩性。

        多线程模型的设计并不是为了帮助开发人员应对多核革命的。事实上,创建一个新的线程需要很多很多的处理器资源,并且把每一个算法分解到并行的线程上会引入很多的开销。大多有用的结构和类的设计并不能被不同的线程同时访问,所以必须添加很多的代码处理这种情况。这些额外的代码是开发人员难以专注主要目的:利用并行执行改善程序性能。

        因为这种多线程模型处理多核并发太复杂了,所以这就是众所周知的重量级并发模型。这引入了额外的负担。由于在框架级别缺乏对多线程互访的支持,为了解决这个问题需要添加太多的代码,这使代码异常的难理解。

        前面提到的与先前.NET提供的多线程模型有关的问题和现代微处理器不断增加的逻辑核心的数目,促使创建新的模型编写并发代码。新的模型就是众所周知的轻量级并发模型,因为它减少了在不同的逻辑核心上创建和执行代码的代价。但是这并不意味着它消除了引入并发导致的所有代价,但是这个模型是为现在多核微处理器的开发设计的。重量型并发模型是在多处理器时代产生的,当时一个电脑可以有很多个只有一个物理核心的微处理器。轻量级并发模型考虑了某些物理核心支持很多逻辑核心的架构。

        轻量级并发模型并不仅仅是调度不同物理核心的负载。它同时增加了对框架级别多线程互访问的的支持,同时使代码更加简单易于理解。

        几乎所有的现代编程语言都将要转向支持轻量型的并发模型。幸运的.Net 4就是其中的一员。所以,所有可以生成.NET应用程序的托管语言都可以利用这种新的模型。

创建良好的基于任务模型的设计

        有的时候,你必须优化一个已存的解决方案以便充分利用并行的特性。在这种情况下,有必须理解已经存在的串行设计,理解采用的并行算法是否会降低伸缩性,否则你必须进行重构以在不引入问题或者产生不同结果情况下获取性能的提升。你可以将问题的一部分或者整个问题创建基于任务模型的设计,然后你就可以引入并行了。当你设计新的解决方案的时候,也可以应用相同的技术。

        依据以下步骤你可以创建有效的基于任务模型的设计:

1.      将每个问题分解成很多的小问题,并且忘记有关串行执行的东西。

2.      向下面一样考虑与每个子问题有关的东西:

可以并发处理的数据,就将数据进行分解实现并发。

需要很多任务和一些复杂并行处理的数据,就分解这些数据和任务来实现并发。

可以并行执行的任务,就分解这些任务来实现并发。

3.      组织你的设计展现并发意图。

4.      确定串联不同子问题需要的任务。尽量的避免产生依赖。

5.      时刻谨记以并发和潜在的并行思想进行设计。

6.      分析并行问题的执行计划需要考虑现在的多核微处理器和将来的架构。为获取更好的伸缩性进行设计。

7.      尽可能的最小化危险的部分。

8.      无论何时,尽可能的使用基于任务模型实现并发编程。

9.      协调步调,不断迭代重复这些步骤。

前面提到的步骤并不意味着所有的子问题都可以成为运行在不同的线程上的并行任务。

当编写代码的时候,根据性能和伸缩性的目标,设计需要考虑并行的可能性,并选择最好设计。并行的思想、将工作分解成不同的任务来完成是很重要的。以这种方式,你就可以根据需要将你的代码并行化。如果你有一个经典的串行执行的设计,通过使用基于任务模型的编程技术使其并行化需要付出很大努力。

 
分类:  翻译

你可能感兴趣的:(并发编程)