Chapter 2 Introduction

如果并行编程是如此困难,为什么会有这么多并行程序?    

未知的

并行编程一直被认为是黑客最难攻克的领域之一。论文和教科书警告过死锁、活锁、竞争条件、非确定性、阿姆达尔定律对扩展性的限制以及过高的实时延迟。这些风险确实存在;我们作者积累了无数年的经验,还有由此带来的心理创伤、白发苍苍和脱发。                   

然而,新技术在初次使用时往往难以掌握,但随着时间的推移,这些技术会变得越来越容易。例如,曾经罕见的开车能力如今在许多国家已司空见惯。这一巨大变化源于两个基本原因:(1)汽车变得更便宜且更容易获得,因此更多的人有机会学习驾驶;(2)由于自动变速箱、自动节气门、自动起动机、显著提高的可靠性以及一系列其他技术改进,汽车变得更加容易操作。                        

同样的道理也适用于许多其他技术,包括计算机。如今,编程不再需要手动操作键盘。电子表格让大多数非程序员能够从他们的计算机中获得几十年前需要专家团队才能实现的结果。最引人注目的例子或许是网络冲浪和内容创作,自21世纪初以来,这些活动已经变得轻松,无需培训或教育背景的人们就能使用各种现在常见的社交网络工具轻松完成。就在1968年,这种内容创作还是一项超前的研究项目[ Eng68],当时被描述为“就像不明飞行物降落在白宫草坪上”[Gri00]。     

因此,如果您希望论证并行编程仍然像许多人目前所认为的那样困难,那么您将承担证明的负担,同时要记住许多世纪以来在许多领域中出现的反例。   

2.1历史并行编程难题

不是记忆的力量,而是它的对立面,  

遗忘的能力,是我们存在的必要条件。    

肖勒姆·阿什

正如书名所示,这本书采取了不同的方法。它没有抱怨并行编程的困难,而是研究了为什么  

并行编程是困难的,然后工作来帮助读者克服这些困难。正如将要看到的,这些困难历来分为几个类别,包括:              

1.并行系统的成本高且相对罕见。  

2.研究人员和实践者缺乏并行系统经验。 

3.公开可访问的并行代码很少。  

4.缺乏广泛理解的并行编程工程学科。  

5.通信的开销相对处理而言较高,即使是在紧密耦合的共享内存计算机中也是如此。   

许多这些历史性的难题正在逐步被克服。首先,在过去的几十年里,由于摩尔定律的影响,多核系统的成本已经从房屋价格的数倍降到了一顿普通餐食的价格[Mo65]。早在1996年,就有论文指出多核CPU的优势[ONH+96]。IBM在2000年将其高端POWER系列引入了同时多线程技术,并在2001年引入了多核技术。英特尔在2000年11月将其普通Pentium系列引入了超线程技术,而AMD和英特尔则在2005年推出了双核CPU。Sun随后在2005年底推出了多核/多线程的Niagara。事实上,到20 08年,找到单核CPU的台式机系统变得越来越困难,单核CPU主要被用于上网本和嵌入式设备。到2012年,即使是智能手机也开始配备了多个CPU。到2020年,安全关键型软件标准开始关注并发问题。                                              

其次,低成本且易于获取的多核系统的出现意味着曾经罕见的并行编程体验现在几乎对所有研究人员和实践者都可用。事实上,学生和业余爱好者长期以来一直能够负担得起并行系统。因此,我们可以预期围绕并行系统的发明和创新水平将大幅提高,随着时间的推移,这种日益增长的熟悉度将使曾经昂贵得令人望而却步的并行编程领域变得更加友好和平凡。                      

第三,在20世纪,大型并行软件系统几乎总是被严格保密的专有技术。相比之下,21世纪出现了许多开源(因此公开可用)的并行软件项目,包括Linux内核[Tor03]、数据库系统[Pos08,MS08]以及消息传递系统[ The08,Uni08a]。本书将主要基于Linux内核,但也会提供大量适合用户级应用的材料。                                             

第四,尽管20世纪80年代和90年代的大规模并行编程项目几乎都是专有项目,但这些项目为其他社区培养了一大批了解开发生产级并行代码所需工程学科的开发者。本书的主要目的是介绍这一工程学科。                     

不幸的是,第五个难题,即通信成本相对于处理成本的高昂,依然普遍存在。这一难题在新世纪受到了越来越多的关注。然而,根据史蒂芬·霍金的观点,光速的有限性和物质的原子性质将限制该领域的进步[Gar07,Moo03]。幸运的是,自20世纪80年代末以来,这一难题一直存在,使得上述工程学科得以发展出实用且有效的解决方案。                                 

处理这些问题的策略。此外,硬件设计者越来越意识到这些问题,因此,也许未来的硬件将对并行软件更加友好,如第3.3节中所讨论的。 

但是,尽管并行编程可能不像通常所宣传的那样困难,但它通常比顺序编程要费力。 

因此,考虑并行编程的替代方案是有意义的。然而,在不了解并行编程目标的情况下,不可能合理地考虑并行编程的替代方案。这一主题将在下一节中讨论。        

2.2并行编程目标

如果你不知道你要去哪里,你就会去别的地方。      

尤吉·贝拉 

并行编程的三大目标(除了顺序编程的目标之外)如下:          

1.性能。

2.生产率。 

3.一般性。

不幸的是,考虑到目前的技术水平,对于任何给定的并行程序来说,最多只能实现这三个目标中的两个。因此,这三个目标构成了并行编程的铁三角,一个过于乐观的希望常常在此三角上破灭。  

以下各节对这些目标进行了详细说明。

2.2.1性能

性能是大多数并行编程工作的主要目标。毕竟,如果性能不是问题,为什么不给自己一个机会:直接编写顺序代码,然后开心点?这很可能更容易,而且你可能会更快地完成更多的工作。   

   

请注意,此处对“性能”的解释范围较广,包括可伸缩性(每个CPU的性能)和效率(每瓦的性能)。 

也就是说,性能的重点已经从硬件转移到了并行软件。这种重点的转移是因为,尽管摩尔定律继续带来晶体管密度的增加,但它已不再提供传统的单线程性能提升。这可以从图2.1中看出。             , 2  这表明,编写单线程代码并简单等待一两年让CPU迎头赶上可能已不再是一个选项。鉴于所有主要制造商近期向多核/多线程系统发展的趋势,对于那些希望充分利用系统全部性能的人来说,采用并行化是最佳选择。    

               

即便如此,第一个目标还是性能,而不是可扩展性,特别是考虑到实现线性可扩展性的最简单方法是降低每个CPU的性能[Tor01]。                                                        

给定一个四核CPU系统,你更倾向于哪个?是单个CPU每秒提供100笔交易但完全不扩展的程序?还是单个CPU每秒提供10笔交易且完美扩展的程序?第一个程序看起来更好,不过如果你恰好有一个32核CPU系统,答案可能会改变。                               

话虽如此,仅仅因为拥有多个CPU并不一定意味着需要全部使用,尤其是在多CPU系统价格最近下降的情况下。关键在于,线程编程主要是一种性能优化,因此它是众多优化中的一种。如果你的程序已经足够快,按照当前的编写方式,就没有必要再进行优化了,无论是通过并行化还是应用其他潜在的顺序优化方法。 同样地,如果你打算将并行性作为优化手段应用于顺序程序,那么你需要将并行算法与最佳顺序算法进行比较。这可能需要一些谨慎,因为许多文献在分析并行算法性能时忽略了顺序情况。                                  

2.2.2生产率   

近年来,生产力变得越来越重要。试想一下,早期计算机的价格高达数千万美元,而当时工程师的年薪只有几千美元。如果一支由十名工程师组成的团队能够提升这台机器的性能,哪怕只是提高10%,那么他们的工资就能得到数倍的回报。            

其中一台机器是CSIRAC,这是最古老的仍保存完好的存储程序计算机,于1949年投入使用[乐04,德06]。由于这台机器是在晶体管时代之前制造的,因此由2000个真空管组成,运行时钟频率为1 kHz,功耗为30 kW,重量超过三公吨。考虑到这台机器只有768字的RAM,可以肯定地说,它没有像当今大型软件项目中常见的生产效率问题。                                

如今,购买一台计算能力如此之低的机器几乎是不可能的。或许最接近的是8位嵌入式微处理器,以著名的Z80[维基08]为代表,但即使是老款的Z80,其CPU时钟频率也比CSIRAC快1000多倍。Z80 CPU拥有8500个晶体管,在2008年以每台不到2美元的价格购买1000个单位。相比之下,软件开发成本对于Z80来说几乎微不足道。                                    

CSIRAC和Z80是长期趋势中的两个点,如图2.2所示。                   该图表展示了过去四十年中每颗芯片计算能力的近似值,在四十年间实现了令人印象深刻的六倍增长。请注意,尽管在2003年遇到了时钟频率墙,但多核CPU的优势使得这种增长得以持续,这得益于每个芯片支持超过50个硬件线程。          

硬件成本迅速下降的一个不可避免的后果是,软件生产力变得越来越重要。仅仅高效利用硬件已不再足够:现在还需要极其高效地利用软件开发人员。这种情况对于顺序硬件来说早已存在,但并行硬件直到最近才成为低成本的商品。因此,只有在最近,高生产力才在创建并行软件时变得至关重要。 

                     

也许曾经,平行软件的唯一目的是性能。然而,现在,生产力正在成为焦点。   

2.2.3通用性

一种证明开发并行软件高成本合理性的方法是追求最大通用性。在其他条件相同的情况下,更通用的软件艺术的成本可以分摊到更多的用户身上,而不太通用的则不然。事实上,这种经济力量解释了对可移植性的狂热关注,这可以视为通用性的一个重要特例。                         

不幸的是,通用性往往以牺牲性能、生产力或两者为代价。例如,可移植性通常是通过适应层实现的,这不可避免地会带来性能损失。为了更普遍地理解这一点,请考虑以下流行的并行编程环境:           

C/C++“锁定加线程”:这一类别包括POSIX线程(pthreads)[ Ope97]、Windows线程以及众多操作系统内核环境,提供了出色的性能(至少在一个SMP系统中),同时也具有良好的通用性。遗憾的是,其生产率相对较低。 

    

图2.3:软件层和性能、生产力和通用性 

Java:这个通用且天生支持多线程的编程环境,被认为比C或C++具有更高的生产率,这得益于自动垃圾回收器和丰富的类库。然而,尽管其性能在21世纪初有了显著提升,但仍落后于C和C++。          

MPI:这一消息传递接口[ MPI08]驱动着世界上最大的科学和技术计算集群,提供无与伦比的性能和可扩展性。理论上,它具有通用性,但主要用于科学和技术计算。许多人认为其生产力甚至低于C/C++“锁定加线程”环境。                            

OpenMP:这组编译器指令可用于并行化循环。因此,它非常适用于此任务,这种特殊性通常会限制其性能。然而,它比MPI或C/C++的“锁定加线程”更容易使用。       

SQL:结构化查询语言[Int92]专用于关系数据库查询。然而,其性能相当出色,根据事务处理性能委员会(TPC)基准测试结果[Tra01]衡量。生产力极佳;事实上,这种并行编程环境使得人们即使对并行编程概念知之甚少或一无所知,也能充分利用大型并行系统。                                        

并行编程环境的完美境界,一个能够提供世界级性能、生产力和通用性的环境,目前还不存在。在这样的完美境界出现之前,我们必须在性能、生产力和通用性之间做出工程上的权衡。其中一个权衡可以通过绿色的“铁三角”来表示5                            如图2.3所示 这表明,在系统堆栈的高层,生产率变得越来越重要,而在底层,性能和通用性变得越来越重要。在底层产生的巨大开发成本必须分摊到同样庞大的用户群体中                    

(因此,通用性的重要性不言而喻),较低层的性能损失很难在较高层恢复。在堆栈的上层,对于特定应用的用户可能非常少,在这种情况下,提高生产力至关重要。这解释了为什么在堆栈的上层倾向于“臃肿软件”:额外的硬件通常比额外的开发人员更便宜。本书旨在帮助那些在堆栈底层工作的开发者,那里性能和通用性最为关键。                         

需要注意的是,生产力与通用性之间的权衡在许多领域已经存在了几个世纪。以钉枪为例,它比锤子更适用于钉钉子,但与钉枪不同的是,锤子除了钉钉子外还可以用于许多其他事情。因此,在并行计算领域出现类似的权衡也就不足为奇了。这种权衡如图2.4所示。在这里,用户1、2、3和4有特定的工作需要计算机来帮助他们完成。对于给定的用户来说,最有效的语言或环境是能够直接完成该用户的工作,而不需要任何编程、配置或其他设置。    

              

不幸的是,一个能够完成用户1要求的工作的系统不太可能完成用户2的工作。换句话说,最有效的语言和环境是特定于领域的,因此从定义上来说缺乏通用性。               

另一种选择是将给定的编程语言或环境定制到硬件系统(例如,低级语言如汇编、C、C++或Java)或某种抽象(例如,Haskell、Prol og或Snobol),如图2.4中中心附近的圆形区域所示。  这些语言可以被视为通用型,因为它们同样不适合用户1、2、3和4所需的任务。换句话说,它们的通用性是以降低生产率为代价的,与领域特定语言和环境相比。更糟糕的是,一种针对特定需求定制的语言,除非能够高效地映射到实际硬件上,否则可能会面临性能和可扩展性问题。                   

铁三角的三个相互冲突的目标——绩效、生产力和通用性——难道没有出路吗?            

事实证明,通常可以使用一些替代方案来实现并行编程,例如在下一节中讨论的替代方案。毕竟,尽管并行编程可能很有趣,但它并不总是最佳工具。    

2.3并行编程的替代方法   

当经验指引道路时,实验就是愚蠢的。    

罗杰·M·巴布森 

为了正确考虑并行编程的替代方案,您必须首先决定您期望并行性为您做什么。如第2.2节所示,并行编程的主要目标是性能、生产力和通用性。由于本书是为软件堆栈底层的性能关键代码开发人员编写的,因此本节其余部分主要关注性能改进。             

请记住,并行处理只是提高性能的一种方法。其他众所周知的方法包括以下几种,大致按难度递增顺序排列:              

1.运行多个序列应用程序实例。

2.使应用程序使用现有的并行软件。

3.优化串行应用程序。

以下各节介绍了这些方法。 

2.3.1顺序应用程序的多个实例

运行多个顺序应用程序实例可以让你在不实际执行并行编程的情况下进行并行编程。根据应用程序的结构,有大量方法可以实现这一点。             

如果你的程序需要分析大量不同的场景,或者需要分析大量独立的数据集,一个简单有效的方法是创建一个单一的顺序程序来执行单一分析,然后使用多种脚本环境(例如bash shell)并行运行该顺序程序的多个实例。在某些情况下,这种方法可以轻松扩展到机器集群中。                              

这种方法可能看起来像是作弊,事实上有些人贬低这类程序为“令人尴尬的并行”。确实,这种方法存在一些潜在缺点,包括增加内存消耗、浪费CPU周期重复计算常见的中间结果以及数据复制增加。然而,它通常非常高效,几乎无需额外努力就能获得显著的性能提升。       

2.3.2使用现有并行软件

如今,能够提供单线程编程环境的并行软件环境已不再短缺,包括关系数据库[Data82]、Web应用服务器和map-reduce环境。例如,一种常见的设计为每个用户提供一个独立的进程,每个进程根据用户查询生成SQL。这些针对每个用户的SQL会运行在一个通用的关系数据库中,该数据库自动并行执行用户的查询。每个用户的程序仅负责用户界面,而关系数据库则全面负责并行性和持久性相关的复杂问题。                            

此外,越来越多的并行库函数,特别是用于数值计算的。更好的是,一些库利用了专用硬件,如向量单元和通用图形处理单元(GPGU)。      

采用这种方法通常会牺牲性能,至少与精心手工编译一个完全并行的应用程序相比是这样。然而,这种牺牲往往通过大幅减少开发工作量而得到很好的回报。        

2.3.3性能优化

直到20世纪初,CPU时钟频率每18个月翻一番。因此,通常更重要的是创造新功能,而不是精心优化性能。如今,摩尔定律“仅仅”增加了晶体管密度,而不是同时增加晶体管密度和每个晶体管的性能,这可能是重新思考性能优化重要性的良机。毕竟,新一代硬件不再带来显著的单线程性能提升。此外,许多性能优化还可以节省能源。             

从这个角度来看,并行编程不过是另一种性能优化手段,尽管随着并行系统的成本降低和普及,这种优化变得越来越有吸引力。然而,值得注意的是,通过并行性获得的加速效果大致受限于CPU数量(但参见第6.5节中的一个有趣例外)。相比之下,传统单线程软件优化所能带来的加速效果要大得多。例如,用哈希表或搜索树替换长链表可以将性能提升几个数量级。这样高度优化的单线程程序可能比其未优化的并行版本运行得快得多,使得并行化变得没有必要。当然,高度优化行程序会更好,尽管这需要额外的开发努力。此外,不同的程序可能有不同的性能瓶颈。例如,如果您的程序大部分时间都在等待来自磁盘驱动器的数据,那么使用多个CPU可能只会增加等待磁盘时间。

事实上,如果程序是从一个按顺序排列在旋转磁盘上的大文件中读取数据,那么并行化你的程序可能会因为额外的寻道开销而变得慢得多。你应该优化数据布局,使文件更小(从而更快读取),将文件分割成可以并行访问的不同驱动器的块,频繁访问的数据缓存在主内存中,或者尽可能减少需要读取的数据量。                                     

并行化可以是一种强大的优化技术,但并非唯一,也不适用于所有情况。当然,程序越容易并行化,这种优化就越有吸引力。并行化被认为相当困难,这引出了一个问题:“究竟是什么让并行编程如此困难?”                                               

2.4什么是并行编程的难点?   

真正的困难可以克服,而想象中的困难是无法克服的。        

西奥多·N·韦尔 

需要注意的是,并行编程的难度既是一个人为因素问题,也是一个并行编程问题的技术属性。我们需要人类来告诉并行系统该做什么,这也就是编程。但并行编程涉及双向通信,程序的性能和可扩展性是机器向人类传达的信息。简而言之,人编写程序告诉计算机该做什么,而计算机则通过最终的性能和可扩展性来评估这个程序。因此,诉诸抽象或数学分析通常会非常有限效用。         

在工业革命中,人机界面通过人为因素研究进行评估,这些研究被称为时间和动作研究。尽管有一些人为因素研究考察了并行编程[ENS05,ES05,HCS+05,SS94],但这些研究过于狭隘,因此无法得出普遍结论。此外,鉴于程序员生产力的正常范围跨越了一个数量级,期望一项经济的研究能够检测到(例如)10%的生产力差异是不现实的。虽然这类研究能够可靠地检测到多个数量级的差异极其宝贵,但最显著的改进往往基于一系列10%的改进。        

因此,我们必须采取不同的办法。

一种方法是仔细考虑并行程序员必须完成而顺序程序员不需要完成的任务。然后我们可以评估给定的编程语言或环境在多大程度上帮助开发人员完成这些任务。这些任务可以分为图2.5中所示的四个类别。  以下各节对每种情况进行了说明。   

2.4.1工作划分   

工作划分对于并行执行是绝对必要的:如果只有一个“全局”工作,则最多只能由一个CPU同时执行,这按定义就是顺序执行。然而,工作划分需要非常谨慎。例如,不均匀的划分可能导致小分区完成时才进行顺序执行[Amd67]。在不太极端的情况下,可以使用负载均衡来充分利用可用硬件,恢复性能和可扩展性。                    

尽管分区可以显著提高性能和可扩展性,但也可能增加复杂性。例如,分区会使得处理全局错误和事件变得更加复杂:一个并行程序可能需要执行非平凡的同步操作,以安全地处理这些全局事件。更广泛地说,每个分区都依赖某种形式的通信:毕竟,如果某个线程不进行通信,它将毫无作用,也就无需执行。然而,由于通信会产生开销,粗心的分区选择可能导致严重的性能下降。             

此外,必须经常控制并发线程的数量,因为每个线程都会占用公共资源,例如CPU缓存中的空间。如果允许过多的线程同时执行,CPU缓存将会溢出,导致高缓存未命中率,从而降低性能。相反,为了充分利用I/O设备,通常需要大量线程来重叠计算和I/O操作。  

最后,允许线程并发执行大大增加了程序的状态空间,这使得程序难以理解和调试,降低了生产效率。在其他条件相同的情况下,状态空间更小且结构更规则的程序更容易理解,但这既是一个人因工程问题,也是一个技术和数学问题。好的并行设计可能具有极其庞大的状态空间,但由于其结构规律而易于理解;而糟糕的设计即使状态空间相对较小也可能难以理解。最好的设计利用了令人尴尬的并行性,或将问题转化为一个有令人尴尬的并行解决方案的问题。在这两种情况下,“令人尴尬的并行”实际上是一种丰富的资源。目前的技术已经列举了一些好的设计;需要更多的工作来对状态空间的大小和结构做出更普遍的判断。                                        

2.4.2并行访问控制

给定一个单线程的顺序程序,该单线程可以完全访问程序的所有资源。这些资源通常是内存中的数据结构,但也可以是CPU、内存(包括缓存)、I/O设备、计算加速器、文件以及其它资源。              

第一个并行访问控制问题在于,对给定资源的访问形式是否依赖于该资源的位置。例如,在许多消息传递环境中,局部变量访问通过表达式和赋值实现,而远程变量访问则使用完全不同的语法,通常涉及消息传递。POSIX线程环境[Ope97]、结构化查询语言(SQL)[Int92]以及分区全局地址空间(PGAS)环境如通用并行C(UPC)[ EGCD03,CBF13]提供隐式访问,而消息传递接口(MPI)[ MPI08]提供显式访问,因为对远程数据的访问需要显式的消息传递。                

另一个并行访问控制的问题是如何协调线程对资源的访问。这种协调通过各种并行语言和环境提供的大量同步机制来实现,包括消息传递、锁定、事务、引用计数、显式定时、共享原子变量和数据所有权。许多传统的并行编程问题,如死锁、活锁和事务回滚,都源于这种协调。该框架可以进一步扩展,以比较这些同步机制,例如锁定与事务内存[MMW07],但这种扩展超出了本节的范围。(有关事务内存的更多信息,请参见第17.2节和第17.3节。)                                

2.4.3资源分区和复制

最有效的并行算法和系统充分利用资源并行性,因此通常明智的做法是通过分区写密集型资源和复制频繁访问的读为主资源来开始并行化。这里提到的资源主要是数据,可能分布在计算机系统、大容量存储设备、NUMA节点、CPU核心(或芯片或硬件线程)、页面、缓存行、同步原语实例或代码的关键部分。例如,基于锁定原语的分区被称为“数据锁定”[BK85]。               

资源划分通常依赖于具体应用。例如,数值应用经常按行、列或子矩阵划分矩阵,而商业应用则经常划分写密集型数据结构和读主要数据结构。因此,一个商业应用可能会将特定客户的资料分配给大型集群中的少数几台计算机。应用可能静态地划分数据,也可能随时间动态改变划分方式。                

资源分区非常有效,但对于复杂的多链接数据结构来说却相当具有挑战性。            

2.4.4与硬件交互   

硬件交互通常是操作系统、编译器、库或其他软件环境基础设施的领域。然而,开发人员在处理新型硬件特性和组件时,往往需要直接与这些硬件打交道。此外,在榨取给定系统性能的最后一丝提升时,可能也需要直接访问硬件。在这种情况下,开发人员可能需要根据目标硬件的缓存几何结构、系统拓扑或互连协议来定制或配置应用程序。                         

在某些情况下,硬件可能被视为一种受分区或访问控制的资源,如前几节所述。                

2.4.5综合能力

尽管这四种能力是基础,良好的工程实践会利用这些能力的组合。例如,数据并行方法首先将数据分区以减少跨分区通信的需求,然后相应地划分代码,最后映射数据分区和线程,以最大化吞吐量同时最小化线程间通信,如图2.6所示。                       开发人员可以单独考虑每个分区,大大减少相关状态空间的大小,从而提高生产率。尽管有些问题无法分区,但巧妙地转换为允许分区的形式有时可以显著提升性能和可扩展性[Met99]。             

2.4.6语言和环境如何帮助这些任务?

尽管许多环境要求开发人员手动处理这些任务,但也有长期存在的环境能够显著提高自动化水平。SQL就是这类环境的典型代表,其许多实现可以自动并行化单个大型查询,并且还能自动化独立查询和更新的并发执行。                     

这四个任务类别必须在所有并行程序中执行,但这当然并不意味着开发人员必须手动执行这些任务。随着并行系统的成本降低和可用性提高,我们可以预期这四个任务将越来越自动化。     

2.5讨论

在你尝试之前,你不知道自己不能做什么。 

亨利·詹姆斯 

本节概述了并行编程的困难、目标及替代方案。随后讨论了并行编程为何难以实现,并提出了一种高层次的方法来应对并行编程的难题。那些仍然坚持认为并行编程不可能实现的人,应该回顾一些较早的并行编程指南[Seq88,Bir 89,BK 85,Inm 85]。安德鲁·比雷尔在其专著中的一段话尤其发人深省[比雷尔89]:                                      

编写并发程序被认为既奇特又困难。我认为并非如此。你需要一个提供良好原语和合适库的系统,需要基本的谨慎和细心,需要掌握一系列有用的技巧,并且需要了解常见的陷阱。希望本文能帮助你认同我的观点。                       

这些较早的指南的作者在20世纪80年代就已经很好地应对了并行编程挑战。因此,在21世纪,拒绝迎接并行编程挑战是没有任何借口的!          

现在我们准备进入下一章,该章节深入探讨了并行软件底层并行硬件的相关特性。               

内容概要:本文详细介绍了基于滑模控制(SMC)和H∞控制相结合的方法应用于永磁直线同步电机(PMLSM)的鲁棒控制。首先阐述了PMLSM的基本数学模型及其物理意义,包括d-q坐标系下的电压方程和运动方程。随后解释了滑模控制的工作原理,重点在于如何构建滑模面并确保系统沿此面稳定运行。接着讨论了H∞控制的目标——即使在不确定条件下也能保持良好的性能表现。文中还提供了具体的Matlab代码实例,展示了如何利用Matlab控制系统工具箱进行H∞控制器的设计。最后给出了一段完整的Matlab程序框架,演示了两种控制方法的具体实现方式。 适合人群:从事电机控制领域的研究人员和技术人员,尤其是那些想要深入了解滑模控制和H∞控制理论及其在实际工程中应用的人士。 使用场景及目标:适用于需要提高永磁直线同步电机控制系统抗干扰能力和鲁棒性的场合,如工业自动化生产线、精密加工设备等。通过学习本篇文章提供的理论知识和编程技巧,读者能够掌握这两种先进控制策略的应用方法,从而提升自身解决复杂控制问题的能力。 其他说明:文中所涉及的内容不仅限于理论讲解,还包括了大量的实战经验分享,有助于读者快速上手并在实践中不断改进自己的设计方案。同时鼓励读者积极尝试不同的参数配置,以便找到最适合特定应用场景的最佳解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值