码迷,mamicode.com
首页 > 其他好文 > 详细

像鸟一样思考更好的并行编程

时间:2018-05-15 22:54:48      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:Java   并发编程   高并发   高可用   

介绍

编写一个应用程序并行运行很困难,对吧?我的意思是,它一定很难,否则我们会看到各处的并行程序。我们所看到的都是平滑的并行应用程序,可以毫不费力地使用每个可用的核心。相反,多线程应用程序是例外而不是规则。

编写并行程序似乎有两个主要障碍:

  • 学习您选择的语言提供的并行编程结构和/或约定

  • 可视化您的并行程序的功能

第一项似乎很明显:休息一下,学习所选编程语言的并行功能,然后离开你 - 并行程序将从你的编译器中跳出。除非那天下午通常会变成几天,这通常会变成一段更长的时间,而你选择的语言的平行特征的含义,并发症和后果则会被驯服。

第二项似乎应该提到几乎是微不足道的。毕竟,开发一个新计划的第一步是想象它的主要组成部分以及它们将如何运作。除了我们通常将我们的新程序可视化为顺序代码组件,以便我们稍后(如果必须的话)将某些并行的东西“栓上”。正是这种思维框架使我们从一开始就走上了错误的道路。

相反,我们需要考虑像鸟这样的程序。或者说,成群的鸟儿。

背景

Avian计算项目是通过改进我们对并行编程的思考来改善并行编程的一种方式。Avian Computing鼓励我们将并行程序可视化为一群鸟,每个鸟(线程)独立并异步地执行操作,但它们同时作为一群来完成程序的目标。

我们都熟悉鸟类:它们被孵化出来,四处飞翔寻找食物,产卵并孵化自己的鸟类,然后死亡。Avian Computing将这些基本的鸟类行为转化为开发人员可以利用的编码框架来快速开发工作并行程序的原型。从构建这个工作原型获得的知识深度和见解可以简化最终软件产品的开发。

Avian计算的实现

并发资源管理器(ConcX)是用Java编写的Avian Computing的概念的免费开源实现。ConcX为用户提供了一个可以创建和配置新鸟的GUI屏幕。配置完成后,可以启动小鸟并在进度条上监控其活动。配置好的鸟群可以保存为一个“群”,可以根据需要重新加载和运行。

技术分享图片

一旦孵化(开始),每只鸟(线)遵循标准生命周期; 它寻找食物,消化找到的任何匹配的食物,储存任何产生的食物,然后小睡一会儿。在配置的耐力时限内找不到食物的鸟类将因饥饿而死亡。活得太久的鸟会死于老年。成功吃足以满足可配置设置的鸟类将复制(重复自己)。这个标准生命周期允许使用简单自然的词汇来处理线程管理的复杂性,这些词汇几乎可以直观地理解。

ConcX依赖于Linda协调语言来从共享虚拟关联存储器(称为元组空间)中放置和检索对象。Linda起源于1986年,由Sudhir Ahuja,David Gelernter和Nicholas Carriero创作。Linda是几个主要产品的基础,包括Sun的JavaSpaces,IBM的TSpaces等等。

ConcX使用称为TupleTree的Linda元组空间的简化版本。鸟类通常配置为在TupleTree中食用和储存食物豆荚。例如,RedPod可以被配置为吃RedPods的任何鸟食用,并且将被所有其他鸟类忽略。在消化它的食物荚后,一只鸟会将加工后的物体存放回TupleTree,通常作为不同种类的食物荚(例如BluePod),以供不同的鸟类食用。

Linda(及其派生,TupleTree)提供了一个安全,简单和强大的消息传递机制。在ConcX中,TupleTree允许在用户编写的代码中没有任何特殊的代码或注意事项的情况下共享对象,因为TupleTree同步(锁定或以其他方式提供独占访问)所有与其底层数据存储交互的方法。

使TupleTree对所有锁定负责,确保鸟儿接收的任何食物吊舱(物体)完全由该鸟类拥有,而不会使用锁定和互斥等使用户代码混乱。这意味着任何接收到食物吊舱的鸟都是免费的在没有来自任何其他鸟类的争用或干扰的情况下对该食品盒进行任何改变。在做出任何必要的改变之后,该鸟可以将其食物吊舱放回TupleTree,在那里不同种类的鸟会吃它并进行改变。

平行思维的简单范例

ConcX提供的Addx场景是Avian计算概念如何生成更简单的并行代码的直接示例。Addx场景的目标是通过对每个值执行一系列数学运算来处理一系列值,直到计算出最终值并保存为止。数学运算必须始终以相同的顺序执行。

在标准的顺序编码中,我们将通过获取下一个值,执行第一个数学运算,然后第二个数学运算,然后第三个数学运算等开始可视化一个循环,直到计算出最终值为止,该值为保存,然后循环重复。看起来相对简单,并且运行速度尽可能快。其最大吞吐量取决于执行单线程的一个处理器的速度。

为了更快速地处理更多的值,需要使用多个处理器,这就是棘手的问题。正常的解决方案是创建一个线程池,每个线程执行上述的顺序代码。但是这会使处理复杂化,因为并行代码必须 确保输入值仅由一个线程处理,并且不会跳过输入值,同时确保不会发生死锁和活锁。很难想象线程可能会互相干扰的所有可能的方式 - 在客户的站点上展示了多次新的令人惊讶的失败模式。更不用说必须为每个运行时环境(笔记本电脑vs大型机等)预先配置和编译多个版本的应用程序。

Addx(Avian)解决方案配置了一个任意数量的鸟群,每只鸟只吃一种食物,并且在将其作为不同类型的食物放回之前,只对该食物执行一次数学运算。通过适当配置食物和储存的食物,保证数学操作的正确顺序。例如,Bird1吃Food1,对其执行数学运算,并将其存储为Food2。Bird2吃Food2,对它进行数学运算,并将其作为Food3存储。Bird3吃Food3,等等。这也可以更简洁地表达为:

食物1 - > Bird1 - > FOOD2 - > BIRD2 - > Food3 - > Bird3。。。.Foodn - > Birdn。

以下简化图说明了Avian并行性。

  • 在下面的生命周期1中,所有五只鸟在大约同一时间开始飞行,但只有Add1Bird找到任何食物。它对该值执行操作,然后将其作为只有Add2Bird吃的食物放回到TupleTree中。

  • 在生命周期2中,Add1Bird和Add2Bird都可以找到食物,以便他们都执行各自的操作,然后将其食物存储回TupleTree。

  • 在生命周期3中,Add1Bird,Add2Bird和Add3Bird都可以找到它们的食物种类,处理它们并将它们放回到TupleTree中。

技术分享图片

大约第五个循环通过它们的生命周期(找到食物,消化它,储存它和午睡),所有五只鸟同时从TupleTree进食,处理它们的荚,并将它们更新的荚储存在树中。上面只画了5只鸟,但很容易想象将这个图放大到包括20只或50只或100只鸟,它们都将同时运行(飞行),所有这些都遵循相同的简单和自然的模式。就像真正的鸟类一样,如果任何鸟类寻找食物并且没有找到它,它就会等待一会儿,然后再次尝试。

重要提示:如图所示这鸟不步调一致操作的简化图。每只小鸟以其自己的个体速率生活,因为每次小睡时,它会随机选择一段时间(在可配置的范围内)。这意味着随机短时间小睡的小鸟会比随机长时间小睡的小鸟更快地完成其生命周期。随着时间的推移,午睡的时间长短会趋于平缓,所以一段时间以后会很慢。在现实生活中,Add5Bird(或任何其他鸟)开始吃之前可能需要3或10或15个周期。

配置鸟类

ConcX提供GUI屏幕来添加,配置和启动鸟类。GUI屏幕还可以在鸟儿飞行时提供动态的实时状态更新。以下屏幕截图显示了运行Addx场景的五只小鸟。屏幕右侧的进度条实时显示每只鸟的成功。每只鸟的进度条越长,鸟成功吃的次数就越多。

技术分享图片

由于每只鸟都有用户可选择的食物类型,因此重新排列数学运算的顺序很简单。只需更改选定的食物并重新运行即可。如果任何鸟的配置不合适,它将无法找到食物,其进度条也不会增长。

“食物供应”选项卡包含食物容器进度条,可以实时动态显示可用食物容器的数量。当运行结束时,TupleTree选项卡显示其包含的食物荚的时间戳列表以及每个食物荚内容的简要摘要以及每个食物荚和哪些鸟执行的交易。

上述功能都集成到并发资源管理器中,允许您交互式地探索和开发并行程序。一旦你了解了如何将程序分解为可以并行运行的子步骤,则可以使用所选择的编程语言对应用程序进行编码。

使用代码

下面显示了Add3Bird的完整Java代码。它只有43行,几乎一半(19)的行可以是注释或空白(用于视觉分离的空白或单个花括号)。Add3Bird所需的唯一代码是afterDigestion方法的重写,它所做的只是将3添加到它找到的任何非空食品盒中。查找窗体并将其存储回树中都由BasicBird框架处理,使开发人员的工作变得更轻松。

技术分享图片

对于上面的代码最重要的是,在这段代码中没有锁定或同步或互斥,因为它全部由TupleTree和ConcX框架处理。所有的多线程并行代码都在后台进行管理,因此用户可以专注于如何将主要任务划分为鸟类可以并行处理原子的小尺寸碎片。

虽然上述任务可能看起来过于简单,但它实际上只是更复杂场景的模板。例如,如果Add1Bird被一只抓住10毫秒声音的鸟取代并且Add2Bird被替换为对其执行快速傅里叶变换的鸟并且Add3Bird被替换为试图将所得输出与其他先前处理的结果等。如果第二只鸟跟不上第一只鸟,而不是试图修改它以加快运行速度(并且可能引入错误),那么首选的Avian解决方案就是添加另一个实例(或另外10个实例)第二只鸟。

兴趣点

Avian Computing的开发旨在鼓励用户基于天生平行的模型(例如鸟群)来形象化他们的并行程序。蜜蜂蜂群,鱼群或马群也可以作为模型,因为它们都包含多个独立运行并且异步运行的角色,同时也可以一起工作。

ConcX是由开发人员/实验者共同创建的。这是一个交互式环境,允许用户启动和停止鸟类的各种组合和配置。虽然每只鸟的飞行都有一个不断更新的进度条,以显示它的成功程度和可用的食物供应量。飞行结束后,可以检查鸡群的结果以及每只鸡的事件历史记录。

Avian Computing和ConcX实现的概念旨在成为培训轮子,帮助我们的单线程思维思考并讨论并行程序。

要详细了解Avian Computing的基本概念以及为什么我们需要帮助来思考并行程序,请访问Avian Computing网站。如果您准备尝试一下,可以从Avian网站或SourceForge下载ConcX-2.x.zip(jar文件,lib文件和flock文件)。请务必同时下载“Avian Computing入门指南”用户指南,因为它包含安装信息以及大约十几种并行方案,例如并行计算Pi,用餐哲学家Probelm,BarberShop场景等。

针对上面的技术我特意整理了一下,有很多技术不是靠几句话能讲清楚,所以干脆找朋友录制了一些视
频,很多问题其实答案很简单,但是背后的思考和逻辑不简单,要做到知其然还要知其所以然。如果想
学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以
加我的Java进阶群:744642380,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分
享给大家


像鸟一样思考更好的并行编程

标签:Java   并发编程   高并发   高可用   

原文地址:http://blog.51cto.com/13742357/2116673

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!