.NET 4.0技术系列之
 
.NET并行计算技术基础(1)
 
 
开篇语:
 
   这是一个系列文章,系统介绍.NET 4.0中引入的并行扩展(包括任务并行库TPL和PLINQ)开发技术。
   本系列文章中所有示例代码在VS2010 BETA1+Windows 7 RC下调试通过。
 
 
   本系列文章的主要内容来自是本人将在电子工业出版社出版的新作中的一章,出于技术共享与交流目的发布,期望业界对并行计算有丰富经验的工程师指出疏漏,也希望网友提出宝贵建议。
 
   作者金旭亮拥有本系列文章所有版权,未经本人许可,不允许将此序列文章及相关示例用于商业目的,除此之外,在网络上出于知识共享目的的复制转贴不受限制。
 
  反馈方式:
  
   在我的两个技术博客上直接回贴:
 
 
  发邮件至:
 
 
                           2009.9.9
 
===========================================================
 
     
 
随着多核CPU的普及和互联网的迅速发展,计算已经进入并行的时代,这种并行计算有两种主要的形式,一种着眼于充分挖掘单台计算机的硬件潜力,通常以多线程协作的方式完成指定的工作任务;另一种着眼于利用互联的计算机所共同拥有的计算能力,将一个工作任务分发到多台计算机上同时处理,通过多台计算机的相互协作完成单台计算机所无法完成的工作任务。
         第一种计算形式在过去一直都是使用线程来实现的,而在.NET 4.0中,又在线程的基础上向软件工程师提供了一个“并行扩展(Parallel Extensions)”,从一个更高的抽象层次简化多线程应用程序的开发,这也是本章要介绍的主要内容。
         第二种计算形式依赖于多台计算机的相互协作,本质上是一种分布式的软件系统,在.NET平台上,WCF是开发这类型软件系统的强大工具。本书第9篇的相关章节将介绍WCF技术。
 
19.1 并行计算概述
 
人们在谈论到计算机技术的飞速进步时,经常引用美国著名科幻小说作家Bruce Sterling[1]的一段名言:
 
I used to think that cyberspace was fifty years away. What I thought was fifty years away, was only ten years away. And what I thought was ten years away... it was already here. I just wasn't aware of it yet.
 
    译为中文这段话的大致含义是
    我曾经认为网际空间cyberspace指互联网这个虚拟的空间至少要有50年才会影响到我们。那些我认为要50年之后才会影响我们的东西,往往只需要10年就成为现实……。而那些我认为10年之后才会影响我们的东西,现在已经在那儿摆着了,而我甚至还没有意识到它已成为现实!
         并行计算就是这样的一个例子,它静悄悄地走来,却于静寞中引发了一场软件技术的变革,当人们开始意识到并行计算对日常生活的影响时,才突然发现,原来并行计算已无所不在。


[1] http://en.wikipedia.org/wiki/Bruce_Sterling 有对Bruce Sterling本人及其作品的介绍。
 

19.1.1 并行计算是计算的未来

         从集成电路***到计算机领域开始,CPU的计算能力一直在持续地增长。其中有一个著名的“摩尔定律”描述了这一发展趋势。
 
趣闻轶事:
“摩尔定律”的提出者是Intel公司的创始人之一Gordon E. Moore1965年他发表了一篇论文,在论文中他针对集成电路技术说过这么一段话:
       “使用最低成本设计出来的元件其复杂性每年大约增加一倍。可以确信,即便不是有所加快,在短期内这一增长率也会继续保持。从长远的观点来看,这一增长率应该会略有变动。尽管没有充分的理由来证明,(但我认为)这一增长率至少在未来十年内几乎维持为一个常数。这意味着到1975年时,以最小的成本制作出来的单个集成电路将拥有65000个元件,而我相信这么庞大的电路将可以被集成到一块小小的芯片中”。
       这就是“摩尔定律”的原型。1975年,Gordon E. Moore修改了“定律”,将其中的“每年”改为“每两年”。而他的另外一名同事,在“摩尔定律”的基础上又提出了一个“修订版”的“摩尔定律”,新版定律指出,每18个月,集成电路的性能将提升一倍。尽管摩尔本人坚持:“我从没说过集成电路中的元件数量每18个月增加一倍”,但他的声音很快被淹没了,“18个月”作为集成电路的“发展周期”,开始以“摩尔定律”广为人知。
       1965年至今,虽然期间有许多人都曾说:摩尔定律已不再有效,但事实却证明这一定律与集成电路技术发展的实际情况相当吻合。到底摩尔定律能用多少年,现在谁也无法下这个结论,还是只能交给时间。但不管怎样,从“摩尔定律”上面人们还是能看到计算机科学家那种深邃的洞察力和让人佩服的预见能力。
 
         对于传统的(非并行)应用程序,往往会随着硬件运行速度的提升而运行得更快。举个例子,许多早期的跑在286/386/486上的一些动作类和射击类游戏,如果不作修改地运行于现在的高性能CPU上,其运行速度可能会快到没有人再能玩这些游戏了。这就是计算机硬件技术的发展给软件所带来的直接好处:代码不用或仅略加修改,程序就拥有更快的运行速度。
         然而,这种免费的午餐是无法永远提供的,其原因在于CPU速度无法无限提升。因为现有的CPU技术需要受到物理法则的限制:
    当晶体管“瘦身”到很小时,由于控制电流的晶体管门(transistor gate) 以及氧化栅极(gate oxide)距离将非常贴近,因此,将发生电子漂移现象(electrons drift)。如果发生这种情况,晶体管会失去可靠性,原因是晶体管在这种条件下无法有效控制电子的运动,从而难于让其能维持稳定的“1”或“0”状态。
         为了能突破这一物理限制而继续提升CPU的计算能力,CPU走向了另一个条路——多核,将多个CPU处理核心集成为单一的整体,称其为“多核CPU”。这样一下,虽然每个CPU处理核心的主频都没有提高,但通过将计算任务合理地分配在多个CPU处理核心上运行,我们同样能达到加快CPU处理性能的目的。
         双核CPU是第一个得到广泛应用的产品,当前几乎所有的新购置的个人电脑都配置了双核CPU,而Intel宣布2009年将为台式机和笔记本电脑生产四核CPU(新四核CPU基于一个代号为“Nehalem”的微架构)。
         简言之:
    如果不对CPU技术作颠覆性的变革,那么,基于现有技术架构的CPU已基本走完了通过提升主频而获取更高性能之路,必须走向多核之路,其特点是:
         1)每个的主频都不算高
         2)在设计CPU架构时,针对并行的工作负载进行了专门优化。
         CPU的“多核”发展趋势对软件技术有重大影响。
    因为CPU的多核化要想真正地发挥效益,必须依赖于精心设计的软件,这种软件本身必须具备将工作任务划分为多个可并行执行的子任务的能力,在操作系统(或特定的软件运行平台)的支持下,将这些任务分配给计算机所配备的多个CPU处理核心并发执行,并且能够在这些子任务运行结束后,将这些结果组合起来,得到最终的处理结果。这就是拥有“并行计算”能力的软件系统。
         开发“并行计算”软件系统,对软件工程师提出了新的挑战,因为开发并行程序要比串行程序难得多。软件工程师必须转换思路,在开发新的软件系统时,从一开始就考虑到并行计算的特点,并对此进行特定的设计,才能充分利用现有硬件基础设施的强大处理能力,开发出高性能与高可靠性的软件系统,这是一个软件技术发展的必然趋势,也是任何一名软件工程师们都必须认真面对的挑战!
 

19.1.2 并行计算的基本原理

 
并行计算的基本思想并不复杂,那就是将一个复杂的工作任务进行分解,然后,在多个处理器上同时执行这些分解后的子任务。
 首先,我们先谈谈多核CPU中的“核”。

1 CPU与“核”

         现在人们常说:最近我买了一台双核笔记本电脑。这里面的“核(core)”指代什么,它与CPU是什么关系?还有,人们还常说到“处理器(processor)”,貌似这三个都是指同样的东西。
         下面我们就来讨论一下这些概念的含义,弄清楚它们到底指代什么。
         学过物理的人都知道,现代计算机是构造于集成电路技术基础之上,任何一个集成电路,最底层的也是最小的工作单元是一个个的晶体管,多个晶体管构成逻辑模块logic block),一组逻辑模块进而构成功能单元functional unit),例如可完成基本算术运算功能的ALUArithmetic Logic Unit,算术逻辑单元)就是功能单元的一个例子。
         多个功能单元组合起来,就构成了微处理器(micro-processor),微处理器最广为人知的名字就是CPU(Central Processing Unit,中央处理单元)
         最终生产出来的微处理器实际上是一块物理基片(die),经过封装之后就叫作处理器(processor)。
         那么什么是“核(core)”呢?
         核是微处理器中所有可用的功能单元的集合。
         那些直接参与指令执行的功能单元的集合称为“执行核(execution core)”。
         很明显,每个微处理器必定要有一个执行核,否则,它无法执行任何指令,也就不能称其为微处理器了。
 
 
现在就可很清楚“多核”的含义了。所谓多核,其实就是在同一块物理基片上集成两个以上的“执行核”,从而使处理器具备并行执行指令的能力。多核CPU,就是指拥有多个执行核的微处理器,基片封装好之后,就称为“多核处理器”。
         再区分一下另两个概念:多处理器与多核处理器系统。
         如前所述,多核处理器系统是指计算机中的处理器中包容了多个执行核,通常这种计算机只包容有一个多核处理器,否则,此系统应归入“多处理器”系统。
         多处理器系统是指由多个处理器构成的计算机系统,每个处理器自身可以是单核或多核的。
         简单地说:多处理器系统可以看作是一个主板上具有多个处理器插槽的计算机系统。
         从应用软件开发者角度来看,多处理器与多核处理器系统其实是一样的,可以统一地将其看成是计算机中拥有多个可供使用的CPU
   下面,我们再来区分一下另外两个很容易弄混的概念——“并发”与“并行”。
 

2 并发与并行

         并行(Parallelism)”是指多个工作任务在拥有多核CPU(或多个单核CPU)的多处理器计算机上同时执行。在这些工作任务运行的过程中,除非有任务提前结束或者延迟启动,否则,在任一时间点总有两个以上的工作任务同时运行。
    简单地说:只要是“同时”运行的,就可以称之为是“并行”的
    191展示了并行执行的三个工作任务在三个处理器上同时运行的情形,图中黑色的长条表示任务的执行过程。

 

并发(Concurrent”,指“宏观”上计算机可以同时执行多个不相关的工作任务(是“并行”的),但在“微观”角度来看,这些工作任务并不是始终都在运行,每个工作任务都呈现出“走走停停”这种相互交替的状态。
         这里的“宏观”,是指从应用程序开发者层次上看的,时间尺度较大,而“微观”则是指从操作系统的线程管理角度和计算机硬件工程师层次上看的,时间尺度很小。
         192展示了3个工作任务在单个处理器上交替执行的情形。
192中,可以看到通过轮流使用单个处理器,尽管在任何时刻都只有一个工作任务在运行,但在一个比较长的时间间隔内,所有的工作任务都在“并行”运行中。由此可见,“并发”的好处之一就是使有限的处理器资源可以“并行”运行超过处理器个数的多个工作任务。正是由于“并发”有这样的好处,所以在操作系统级别,不管计算机本身是单核系统还是多核系统,都是采用微观上的“并发”来实现宏观上的“并行”,绝不允许一个工作任务长时间地独占某个处理器直到其运行结束。
         再详细解释一下如何利用“并发”实现“并行”。
 
    在单核计算机系统中,操作系统通过“微观”上让每个线程分时使用处理器实现“宏观”上工作任务的“并行”执行(因为工作任务具体是由线程负责完成的),而在多核计算机系统中,尽管在物理架构上直接支持“并行”,允许同时运行多个线程,但由于大多数情况下负责执行工作任务的线程数往往大于可获取的处理器个数,所以,操作系统仍是使用同样的分时调度策略为线程分配处理器。这时,同一个线程有可能在不同的时间段内在不同的处理器上运行。 193展示了属于同一工作任务的多个线程在4个处理器上“跳越”执行的情形。
 
 
理解“并行”与“并发”的区别,是我们开发 “并行程序”的第一步。