现在的位置: 首页 > 综合 > 正文

基于任务模型的软件开发

2013年12月12日 ⁄ 综合 ⁄ 共 4458字 ⁄ 字号 评论关闭

转载于:

http://blog.csdn.net/hou478410969/article/details/7629281

http://blog.csdn.net/hou478410969/article/details/7618290#comments

多核心共享内存下的软件开发

在2005年,Herb Sutter在Dr.Dobb’s Journal上发表了题为“免费午餐结束:软件开发将转向并发编程”的文章。其中他谈到现在又必要在软件开发中考虑并发了,从而充分的挖掘呈指数量级增加的微处理器的潜能获取生产力的提高。现在微处理器厂商一直都在增加处理器的核心,而不是增加时钟频率。软件开发者将不能够依赖增加处理器时钟频率免费获取性能的提升。

现在几乎所有的机器的处理都至少有两个核心。然而,四核和八核的微处理器在服务器、高级工作站上很流行,甚至是高端的便携电脑。拥有更多内核的单个处理器就将要到来。现代化的微处理器提供了新的多核结构。所以,为软件设计和代码开发做一些准备来充分的利用这种架构还是很重要的。使用visual C#2010 和 .NET 4生成的各种不同类型的程序运行在微处理器的一个或者多个核心上。每一个这样的微处理器都可能有不同数目的内核,具有同时执行多条指令的能力。

你可以将多核微处理器想象为内部有多个相互连通的微处理器的包。所有的核心都可以想图1-1中那样访问主存储器。这就是著名的多核共享内存架构。此架构中的内存共享极易导致性能瓶颈。

图 1-1. 共享内存架构图

多核微处理器有很多不同的复杂的微架构,这些设计都是为了提供更强的并行执行能力,提高生产力、减少潜在的性能瓶颈。同时,多核处理器也尽力来减少电能消耗和产生更少的热量。因此,很多现代的微处理器能够根据自己的负载动态的增加和减少每个核心的时钟频率,设置当某些核心不再使用的时候使他们休眠。Windows7和windows server 2008 R2支持一种叫做核心场的新特性。当很多的核心不再使用的时候,就会激活这种特性,此时操作系统就会休眠这些内核。当需要这些内核的时候,操作系统就会唤醒正在休眠的内核。

现在的微处理器工作的时候可以动态的更改每个内核的时钟频率。由于这些内核并不是以固定的时钟频率进行工作,所以很难预测某个指令序列的性能。例如,英特尔的Turbo Boost技术增加活动内核的频率。这个增加内核时钟频率的处理过程也就是著名的overclocking(超频?)。

如果一个内核超负载工作而其他的内核都处于闲置状态,这种技术就允许它以更高的时钟频率运行。如果有很多的内核都超负荷工作,这些内核也会以更高的频率运行,但是不会高于只有一个核心(超负荷运行)的情况。但是微处理器并不能一直保持所有的内核一直超频运行,因为这样会消耗很多的电能,并且温度也上升的很快。由于所有内核超负载运行的平均时钟频率要低于只有一个核心超负载运行的频率。因此,在特定情况下,某些代码运行时的时钟频率高于其他代码,这使测量程序真正的性能成为一种极大地挑战。

多核共享内存与分布式内存系统的区别

分布式内存计算机系统是由很多带有自己私有内存的微处理器组成的,其结构如图1-2所示。每个微处理器都位于一个不同的计算机里,它们彼此之间都有不同类型的通信通道。比如有线和无线网络的通信通道。如果正在一个微处理器上处理的工作需要远程的数据,那么它必须通过通信通道与相应的远程处理器进行通信。运行在分布式内存计算机系统上的并行应用程序广泛使用的通信协议是MPI(Message Passing Interface)。在C#和.NET中使用MPI也能充分利用多核共享内存架构的优势。但是MPI的主要专注改善运行在集群上的应用程序的开发。由于多核共享内存架构中多核之间访问并不需要发送消息,这样就给多核共享内存增加了一个大的开销。

图1-2. 分布式内存系统结构图

图1-3展示了拥有三台机器的分布式内存计算机系统。每个机器都有一个四核的处理器和这些内核使用的内存共享架构。这样,每个处理器的私有内存同时也扮演着其四个内核的共享内存的角色。

一个分布式内存系统强制你考虑数据的分布式,因为每个消息检索的远程数据都可能引入潜在的不确定性。由于你可以添加新的机器节点来增加微处理器的数量,所以分布式内存系统能够提供很大的扩展能力。

图 1-3 .混合架构图

并发编程和多核编程

传统的顺序代码一个指令一个指令的执行,并不能充分的利用多核的优势,因为这些串行执行的指令仅仅能够运行在这些内核中的某一个。使用visual C# 2010编写的顺序代码,如果没有使用.NET 4.0提供的新特性将任务分派到多个核心上,那也是不能充分的利用多核心的优势的。对于已存的顺序代码并不存在一种自动的并发。

并发编程是一种代码充分的利用底层硬件提供的并行执行能力的编程模式。并发编程模式同时运行很多的指令。就像前面所解释的,现在又很多不同种类的并行执行架构,并且对他们就这一话题的细节进行深入分析需要一整本书来展现。

多核编程是一种代码充分的利用多个正在执行的内核来并行的运行很多的指令的编程模型。多核心和多处理器的单台电脑提供了多于一个处理核心。因此,这样的目的就是通过将工作分布到所有可用的核心上完成,从而达到在更少的事件内做更多的事情。

现在的微处理器可以在多样的数据上执行相同的指令,这就是Michael J. Flynn 在1966年他所推荐的Flynns taxonomy所总结的单指令多数据。以这种方式,你可以充分的利用这些向量处理机来减少执行特定算法的执行事件。

这本书同时覆盖了共享内存多核编程和向量处理能力使用的两种并发编程模型的很多细节。这一切的首要目的就是减少算法的执行时间。新的处理能力是你能够为已存的代码添加新的特性。

理解物理线程和软件线程

一个多核的微处理器拥有多于一个的物理处理核心,这些彼此独立的处理单元使得同时并行执行多条执行成为可能。为了充分的利用这些物理核心,我们有必要运行多个进程或者在单个进程内运行多个线程。

然而,每一个物理核心都能够提供多于一个的物理线程,这个就是众所周知的逻辑核心或者逻辑处理器。使用英特尔的Hyper-Threading技术(HT或者HTT)的微处理器为每个物理核心提供了多个架构级别的状态。例如,很多使用HT技术带有四个物理核心的微处理器为每个物理核心提供了两个架构级别的状态,也就是提供了八个物理线程。这就是众所周知的SMT(simultaneous multiithreading)技术,它在微处理器指令级别使用额外的架构级别的状态来优化和增强并行执行能力。SMT技术并没有限制每个物理核心仅仅可以提供两个物理线程;例如,每个物理核心你可以拥有四个物理线程。这并不意味着每个物理线程就代表一个物理核心。在某些特定的场景下,SMT能够为多线程代码提供性能优化。后续的章节将会提供有关这些性能优化方面的例子。

每个运行在windows上的程序就是一个进程。每个进程会创建和运行一个或者多个线程。为了区别先前的提到的物理线程,我们将其称为软件线程。一个进程至少得有一个主线程。一个操作系统调度器为他所调度需要运行的进程和线程公平的分配可用处理资源。Windows调度器为每一个软件线程分配处理时间。当windows调度器运行在多核处理器上时,它必须冲一个物理线程分配处理时间到每一个需要运行指令的软件线程上。你可以讲每个物理线程想象为泳道,每个软件线程想象为游泳者。

每一个软件线程都与它所属的进程共享私有的内存空间,然而它却有自己的堆栈、寄存器和私有局部存储器。

Windows将每个物理线程视为一个可以调度的逻辑处理器。每个逻辑处理器都能都执行同一个软件线程的代码。一个执行多个软件线程代码的进程可以充分的利用物理线程和物理核心来并行执行指令。图1-4中展示了运行在物理线程和物理核心上的软件线程的情况。Windows调度器为了均衡每个物理线程的工作负载,可以决定是否重新指派一个软件线程到另一个物理线程。因为通常有很多其他的软件线程等待处理时间,负载均衡通过组织这些线程的可用资源使得运行这些软件线程称为可能。图1-5中windows任务管理器展示了8个物理线程(逻辑核心和它们的负载)。

图 1-4

图 1-5

负载均衡是这样一种分布实践,它将软件进程上的工作在硬件进程上进行重新分配。然而,成功的实现一个完美的负载均衡需要依赖包括应用程序、工作负载、软件线程的数目、可用的物理线程和负载均衡策略在内的并行实现。

Windows任务管理器和windows资源监视器展示了cpu的物理线程的使用率图表。例如,如果你有一个拥有四个物理核心的微处理器和八个物理线程,这些工具将会展示八个独立的图表。

Windows通过将大量的处理时间指派给每个可用的物理线程的方式运行着成百的软件线程。你可以在windows资源监视器的概述标签页中查看一个指定进程的所有软件线程的数目。CPU仪表盘展示了每个进程的名字,在Threads列中展示了相关联的软件线程的数目,在图1-6中我们可以看到vlc.exe进程拥有32个软件线程。

图 1-6

Core Parking是windows内核能源管理器和内核调度技术,它是为改善多核系统的能效问题而设计的。它不断的跟踪每个物理线程相对其他所有物理线程的工作负载来决定是否让它们中的某些进入睡眠模式。

Core Parking基于工作负载动态的调整正在使用的物理线程的数量。当某个物理线程的工作负载小于某个特定的临界值的时候,Core Parking算法将会尝试通过停止系统中某些物理线程来减少正在使用的物理线程的数目。为了改善这种算法的有效性,当调度软件线程的时候,内核调度器可以给予没有停止的物理线程优先权。它将会尝试让停止的软件线程停顿,这样就可以使他们转换成为一种低耗能的停顿状态。

Core Parking尝试只能调度那些运行带多个软件线程的工作负载,这些线程运行在使用HT技术的微处理器的某个物理核心上。这种调度决定减少了能源消耗。

Windows server 2008 R2支持完整的Core Parking技术。然而,windows 7也使用Core Parking算法和基础设施来平衡运行在带有HT功能的微处理器上的物理线程的性能。图1-7中的资源监视器展示了八个物理线程的活动状态,其中四个是parked状态。

尽管某些物理线程处于parked状态,但是使用.NET 4的方法获取的物理线程的数目还是总的数目。Core Parking技术并不限制可用来运行进程内的软件线程的可用的物理线程的数目。

在特定的工作负载下,一个有八个物理线程的系统在工作负载比较轻时使自己只有两个物理线程,然后在需要的时候再增加运行保留的物理线程。在某些情况下,Core Parking会引入一个额外的潜在因素来调度很多想要并行执行代码的软件线程。所以,在测量并行执行性能的时候,考虑这些影响结果的潜在因素是很重要的。


图 1-7

抱歉!评论已关闭.