R并行编程实战(txt+pdf+epub+mobi电子书下载)


发布时间:2020-08-22 19:57:05

点击下载

作者:(美)西蒙 R.查普尔(Simon R.Chapple)

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

R并行编程实战

R并行编程实战试读:

前言

我们正处于信息爆炸时代。从个人到全世界,生活中的一切都变得越来越与物联网实时关联。据预测,到2020年,世界上的数据将超过现在的10倍,达到惊人的44泽字节(1泽字节相当于2500亿张DVD)。为了解决大数据的规模和速度问题,我们需要巨大的计算、内存和磁盘资源,而为此就需要并行计算。

尽管使用的时间不长,但R作为一种开源统计编程语言,逐渐成为人们分析数据的关键基础技术之一。我敢说R现在是“数据科学家”的主流编程语言之一。

当然,数据科学家可能会部署许多其他工具来处理大数据的一些困难问题,如Python、SAS、SPSS或MATLAB。然而,自从1997年以来,随着开源语言的深入发展,R语言非常流行,在20年中开发了许多存放于CRAN镜像站点的R添加包,这些添加包适用于几乎所有形式的数据分析,从小型数值矩阵到庞大的符号数据集,如生物分子DNA。事实上,我认为R语言正成为“事实上”的数据科学脚本语言,它可以融合许多不同类型的高度复杂数据的分析方法。

R语言自身总是按照单线程来实现的,而且其原有的程序设计并没有应用并行机制。然而,为了达到某些功能的并行目的以及使用并行处理框架,R语言需要借助于某些特别开发的外部添加包。我们将重点关注一些目前技术范围内可用的最好的并行算法。

在本书中,我们将介绍并行计算的各个方面,从单程序多数据(SPMD)到单指令多数据(SIMD)向量处理,包括用R添加包parallel来利用R内置的多核功能、用消息传递接口(MPI)进行消息传递、用OpenCL处理通用GPU(GPGPU)的并行性。我们还将探讨并行性的不同框架方法,从利用任务分配的负载均衡到网格空间处理。我们将通过Hadoop了解云计算中更通用的批量数据处理,以及集群计算中的热门新技术Apache Spark,它更适合大规模的实时数据处理。

我们甚至会探索如何使用真正的数百万英镑的超级计算机。是的,我知道你可能没有这样的计算机,但是在本书中,我们会告诉你如何使用它,以及并行计算的效果。说不定,随着知识的更新,你可以来到当地的超级计算机中心,并说服他们让你进行一些大规模的并行计算!

本书中展示的所有编码示例都具有原创性,选择这些示例的原因是为了不复制其他书中可能遇到的例子。亲爱的读者,选择这些代码的原因是希望能让你与普通读者有一点不同。作为作者,我们非常希望你享受这个过程。本书内容

第1章快速地展示如何利用R的并行版本lapply()来开发笔记本电脑的多核处理功能。我们也通过亚马逊网络服务简要介绍云计算的巨大运行能力。

第2章涵盖标准的消息传递接口(MPI),它是实现高级并行算法的关键技术。在本章中,你将学习如何使用两个不同的R MPI添加包Rmpi和pbdMPI以及底层通信子系统的OpenMPI实现。

第3章通过开发一个详细的Rmpi工作示例完成MPI过程,说明如何使用非阻塞通信和局部进程间消息交换模式,这是实现空间网格并行所必需的。

第4章介绍在真实的超级计算机上运行并行代码的经验。本章还详细介绍开发SPRINT的过程,即一个用C语言编写的可以在笔记本电脑以及超级计算机上运行的并行计算的R包。此外,还说明如何使用自己本地编码的高性能并行算法扩展此添加包,并使其可访问R。

第5章展示如何通过ROpenCL添加包直接应用笔记本电脑的图形处理单元(GPU)的大规模并行和向量处理能力,该添加包是开放式计算语言OpenCL的一个R包装。

第6章介绍并行编程及其性能的科学原理,通过强调想要避免的潜在陷阱来讲述最好的实践艺术,并初步展望了并行计算系统的未来。

在线章节“Apache Spa-R-k”介绍了Apache Spark,现在它成为继Hadoop之后最流行的分布式存储大数据的并行计算环境。你将学习如何设置和安装Spark集群,以及如何直接从R中利用Spark自己的数据框提取。

这一章可以在Packt出版社的主页上下载:https://www.packtpub.com/sites/default/files/downloads/B03974_BonusChapter.pdf

不需要从头到尾依次阅读本书,大多数情况下,每一章节都是可以独立阅读的。阅读准备

要运行本书中的代码,你需要一个最新配置的多核笔记本电脑或台式计算机。你还需要一个合适带宽的网络连接,用于从CRAN(R包的主要在线存储库)下载R和各种R代码库。

本书中的例子主要使用RStudio 0.98.1062、64位R 3.1.0(CRAN发行版)开发,运行于2014年发行的Apple MacBook Pro OS X 10.9.4(具有2.6GHz Intel Core i5处理器和16GB内存)。当然,所有这些例子也应该适用最新版本的R。

本书中的一些示例将无法使用Microsoft Windows运行,但是它们应该可以在Linux的其他版本上运行。每章将详细介绍所需的额外的外部库或运行时的系统要求,并提供有关如何访问和安装它们的信息。读者人群

本书适用于中高级R开发人员,使之掌握利用并行计算功能来执行长时间运行的计算,并分析大量数据。你需要具有一定的R编程知识,并且是一个能力强大的程序员,这样你可以阅读和理解低级语言(如C/C++),并熟悉代码编译过程。你可以认为自己是新型数据科学家,即—个熟练的程序员和数学家。本书约定

在本书中,你会发现一些区分不同信息的文本样式。以下是这些样式的一些例子及其含义。

代码、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟URL、用户输入和Twitter句柄如下所示:“注意使用mpi.cart.create(),它从一组现有的MPI进程映射构造了一个笛卡儿秩/网格。”

代码段如下:

当我们希望注意到代码段的特定部分时,相关行或条目将加粗:

任何命令行输入或输出如下所示:

新术语和重要词都以黑体显示。

表示警告或重要提示。表示提示和技巧。下载示例代码

可以从http://www.packtpub.com

通过个人账号下载你所购买书籍的示例源码。如果你是从其他途径购买的,可以访问http://www.packtpub.com/support,完成账号注册,就可以直接通过邮件方式获得相关文件。

你也可以访问华章网站http://www.hzbook.com

,通过注册并登录个人账号,下载本书的源代码。下载书中彩图

我们还提供了一个PDF文件,其中包含本书中使用的截图和彩图,以帮助读者更好地了解输出的变化。文件可以从以下地址下载:http://www.packtpub.com/sites/default/files/downloads/MasteringParallelProgrammingwithR_ColorImages.pdf

。关于作者

西蒙R.查普尔(Simon R.Chapple)是一位经验丰富的解决方案架构师和首席软件工程师,从事数据分析和医疗信息系统解决方案和应用的开发超过25年。他也是超级计算机HPC和大数据处理方面的专家。

Simon是Datalytics科技有限公司的首席技术官和管理合伙人,带领一个团队建设下一代大规模数据分析平台,该平台建立在一组由高性能工具、框架和系统所构成的可定制的工具集合基础上,可以使从数据采集、分析到呈现的整个实时处理周期,轻松地部署到任何已有的IT操作环境中。

此前,他在Aridhia信息公司担任产品创新总监,为苏格兰的医疗服务供应商建立了多个新系统,包括为苏格兰18周转诊治疗和癌症患者的管理而提供的一体化病人路径跟踪系统,该系统应用了10个单独数据系统的集成(减少病人等待时间,从而提供最好的服务)。他还利用公共云托管监测系统,为实时化疗患者建立了专门的移动系统,该系统在澳大利亚进行了临床试验,受到护士和病人的高度赞扬,“就像在你的起居室里有一位护士……希望所有的化疗病人每天都有天使般的安全舒适的护理环境。”

Simon也是ROpenCL开源软件包的作者之一,该添加包使得用R编写的统计程序可以应用图形加速器芯片中的并行计算能力。

对于SPRINT这一章,我特别要感谢爱丁堡并行计算中心的同事以及本书审阅者Willem Ligtenberg、Joe McKavanagh和Steven Sanderson,谢谢他们的积极反馈。我还要感谢Packt出版社的编辑团队为本书的最终出版付出的辛勤劳动。感谢我的妻子和儿子的理解,他们给我珍贵的时间使我成为一名作者,谨以此书献给我爱的Heather和Adam。

伊丽·特鲁普(Eilidh Troup)是爱丁堡大学EPCC的应用顾问。她拥有Glasgow大学的遗传学学位,现在专注于为广大用户尤其是生物学家提供高性能计算。Eilidh致力于各种软件项目,包括为基于网络的科学数据存储库提供简单的并行R接口(SPRINT)和SEEK。

托斯顿·福斯特(Thorsten Forster)是爱丁堡大学的数据科学研究员。他具有统计学和计算机科学背景,并获得了生物医学科学博士学位,在这些交叉学科研究方面拥有超过10年的经验。

Thorsten利用统计学和机器学习(如微阵列和下一代测序)研究生物医学的大数据分析方法,他曾经是SPRINT项目的项目经理,该项目的目标是允许潜在用户使用R统计编程语言对大型生物数据集应用并行分析解决方案。他还是Fios Genomics公司的联合创始人,该公司是一家大学孵化的提供生物医学大数据研究的数据分析服务公司。

目前,Thorsten的工作是设计用于诊断新生儿细菌感染的基因转移分类器、分析巨噬细胞干扰素激活的转移谱、调查胆固醇对感染免疫的作用,以及研究导致儿童气喘的基因因素。

Thorsten的完整资料可以在http://tinyurl.com/ThorstenForsterUEDIN上获得。

特伦斯·斯隆(Terence Sloan)是爱丁堡大学高性能计算中心EPCC的软件开发小组经理。他在苏格兰中小企业、英国公司以及欧洲和全球合作方面拥有超过25年的管理和参与数据科学和高性能计算项目的经验。

Terry获得过Wellcome Trust(基金号086696/Z/08/Z)、BBSRC(基金号BB/J019283/1)研究基金,以及帮助开发R语言SPRINT添加包的3个EPSRC分布式计算科学基金。他在使用行为大数据进行客户行为分析方面获得过ESRC奖(获奖号RES-189-25-0066、RES-149-25-0005)。

Terry是爱丁堡大学HPC数据科学硕士项目的HPC数据分析、项目准备和论文课程的责任人。

我要感谢Alan Simpson博士,他是EPCC的技术总监、ARCHER超级计算机的计算科学和工程总监,感谢他支持SPRINT的开发及其在英国国家超级计算机上的应用。第1章简单的R并行性

在本章中,你将通过快速学习开发笔记本电脑的多核处理能力来开始探索R语言的并行性的旅程。我们首先看看如何利用云的巨大计算能力。

你将学习lapply()及其变体,它们是由R的核心并行包以及可以让我们利用亚马逊网络服务(AWS)和弹性地图减少(EMR)服务的segue包支持的。对于后者,你将需要AWS建立的账户。

本章使用的例子是一个称为亚里士多德数谜的古老谜题的迭代求解程序。希望这对于你是新的东西,并可以激起你的兴趣。特别选择了一个当并行运行代码时会出现的一个重要问题(即不平衡计算)来进行演示。它也将有助于发展我们的性能基准测试的技能(在并行性中的一个重要考虑),即测量整体计算效率。

本章的例子使用RStudio 0.98.1062以及64位R 3.1.0(CRAN分布),运行在mid-2014苹果MacBook Pro X 10.9.4上(处理器是2.6GHz的英特尔酷睿i5,内存为16GB)。本章中的一些例子无法在Microsoft Windows上运行,但应该可以在Linux的所有版本上运行。1.1 亚里士多德数谜

我们将要解决的谜题是亚里士多德数谜,它是一个六角幻方。谜题需要我们将编号从1到19的19个小薄板放到六角网格中,使六边形板上的每一个水平行和每一个对角对应连线上的小薄板的编号相加都是38。在图1-1中,左边是一个尚未解决的谜题,展示放置小薄板从左上角到右上角的六角网格布局。这幅图的旁边,展示了谜题的部分解,其中两行(小薄板从16和11开始)和4条对角线加起来都是38,位置1、3、8、10、12、17和19是空单元,还有7个未填充的小薄板,为2、8、9、12、13、15和17。图 1-1

有数学头脑的人可能已经注意到可能的小薄板布局的数量为19的阶乘。也就是说,总共有121645100408832000种不同的组合(忽略旋转和镜面对称)。即使利用现代的微处理器,显然也需要相当一段时间来寻找在这12.1亿亿种组合中的一个有效解。

我们将使用深度优先迭代搜索算法来解决这个谜题,用有限的内存换取计算周期。在不付出巨大代价的情况下,我们不能轻易存储每一种可能的布局。1.1.1 求解程序的实现

我们首先考虑如何表示六角形板。最简单的方法是使用一个长度为19的一维R向量,其中向量的指标i表示六角形板的第i个单元。小薄板还未放入行中,板上向量“单元”的值应该为数字0。

接下来,让我们定义一个函数来估计小薄板的布局是否表示一个有效解。作为上面工作的一部分,我们需要指定单元或“行”的不同组合,它们相加得到目标值必须是38,如下所示:

为了实现深度优先求解程序,我们需要处理剩余小薄板的列表来寻找下一个小薄板的位置。为此,我们通过在向量中的第一个和最后一个分量上使用入栈和出栈函数来利用简单栈上的变化。为了让它有所不同,我们将它实现为类,并称为序列。

这是一个简单的S3-类序列,它通过内部维持向量中栈的状态实现了一个双头/双尾栈:

从一些例子的使用中,可以很容易理解序列的实现,如下所示:

我们几乎完成了。这里是placeTiles()函数的实现,placeTiles()函数用来执行深度优先搜索:

该函数利用递归将每一个随后的小薄板放到接下来的可用单元中。因为最多有19个小薄板要放置,所以递归将下降到最多19的水平上(行08)。递归将在没有余下的小薄板可以放置到六角形板上时结束,并且然后对板进行评估(行16)。一次成功的评估将立即展开递归栈(行09),给调用者传送板的最终完成状态(行17)。一次不成功的评估将递归调用的栈后退一步,然后尝试下一个余下的小薄板。一旦一个给定单元中的所有小薄板都用完了后,递归将展开先前的单元,尝试序列中下一个小薄板,递归将再次进行,等等。

函数placeTiles()可以使我们有效地测试一个部分解,让我们尝试本章开始的部分小薄板放置。执行以下代码:下载示例代码

你可以从http://www.packtpub.com

上的账户中下载本书中的示例代码。如果你在其他地方购买了本书,可以访问http://www.packtpub.cpm/support并注册,示例代码文件将通过电子邮件发给你。

可以通过以下步骤下载代码文件:

·使用你的电子邮件地址和密码登录或注册我们的网站。

·鼠标悬停在顶部的SUPPORT选项卡上。

·单击Code Downloads&Errata。

·在Search框中输入书名。

·选择你想下载代码文件的书。

·从下拉菜单中选择你是从哪里购买这本书的。

·单击Code Download。

你还可以通过在Packt出版社网站中的本书网页上单击Code Files按钮来下载该代码文件。这个页面可以通过在Search框输入书名来访问。请注意,你需要登录到你的Packt账户。

一旦下载了文件,请确保你的解压缩或提取文件程序是最新版本:

·Windows系统的WinRAR/7-Zip

·Mac系统的Zipeg/iZip/UnRarX

·Linux系统的7-Zip/PeaZip

本书的代码包也存储在https://github.com/PacktPublishing/repo-sitoryname

上的GitHub中。从https://github.com/PacktPublishing/上丰富的书籍目录和视频中,我们也可以下载其他的代码包。把它们找出来!

遗憾的是,我们的部分解并不会产生一个完全解。显然,我们还需要更加努力。1.1.2 改进求解程序

在我们讨论并行求解程序之前,首先研究目前的串行执行的效率。在现有的place-Tiles()实现中,放置六角形小薄板直到板完成,然后对它进行评估。我们以前测试的部分解有7个未处理的单元,需要调用7!=5040次evaluateBoard(),并且总共有13699种小薄板放置方法。

我们可以进行的最明显的改良是当我们放置小薄板时对每个小薄板进行测试,然后检查目前的部分解是否是正确的,而不是等到所有的小薄板都放置完。直观地说,这将显著地减少我们必须检测的六角形板的布局数量。让我们实现这一改变,然后比较性能的差异,并了解从这样额外的实现工作中带来的收益:

为提高效率,evaluateCell()函数确定需要检查哪些行,基于执行直接检查cell-Lines放置的单元。cell-Lines数据结构很容易从all_Lines中进行编译(你甚至可以编写一些简单的代码来生成它)。板上的每一个单元都需要3个特定行进行测试。因为任意给定的测试行可能没有填满小薄板,所以evaluateCell()包含了一个检查来确保它只适用于当行完整时和为38的测试。对于一个不完整行,检测是为了保证和不超过38。

我们现在可以增强placeTiles()来调用evaluateCell(),如下所示:

测量执行时间

在应用这种改变之前,需要先基准测试当前的placeTiles()函数,这样我们才能判断最终的性能改善。为此,我们介绍一个简单的时间函数teval(),这个函数将使我们能够准确测量在执行给定的R函数时,处理器完成了多少工作。观察以下代码:

teval()函数使用一个内部系统函数pro.time()来记录当前的活动用户和系统周期以及R进程的时钟时间(不幸的是,当在Windows系统上运行R时,该信息是不可用的)。它捕获测量的R表达式运行前后的这个状态并计算总体持续时间。为了有助于确保时间的一致性水平,调用一个抢占式的碎片收集,但应该注意的是,这并不会在时间周期内的任何一点排除R执行碎片收集。

因此,让我们在现有的placeTIles()上运行teval(),如下所示:

现在,让我们在placeTiles()中做一些改变以便调用evaluateCell(),然后通过以下代码再次运行它:

这是一个非常棒的结果!这一改良使运行时间降低了200倍。显然,你自己的绝对时间可能会根据使用的机器而有所不同。基准测试代码

对于真正的比较基准测试,我们应该多次运行测试并从一个完整系统启动运行,确保没有缓存的影响或者可能影响我们结果的系统资源占用问题。对于特定的简单示例代码,它并不执行文件I/O或网络通信,处理用户输入或使用大量内存,我们应该不会遇到这些问题。这类问题通常由多个运行时间内的显著变化表明,高百分比的系统时间或实际运算(elapsed)时间实质上大于用户+系统时间。

这种性能分析和改进与本章后面的内容同样重要,我们将直接支付云上的CPU循环。因此,我们想要代码尽可能地高效。

代码植入

为了对我们代码的行为有一些更深入的了解,例如程序执行期间函数被调用了多少次,我们或者需要添加显式仪表,如计数器和打印语句,或者使用外部工具,如Rprof。现在,我们要看看如何应用基本的R函数trace()提供一个通用机制来描述函数被调用的次数,如下所示:

trace()函数使我们能够每次调用被追踪的函数时执行一段代码。我们将利用这个函数来更新在全局环境中创建的一个特定的计数器(profile.counter)用来跟踪每次调用。

trace()

只有当跟踪显式编译为R本身时这个函数才是有效的。如果你正在使用Mac OS或Microsoft Windows的R的CRAN分布,那么这个设备就会被打开。跟踪引入一点,即使并未在代码中直接使用,因此它往往不编译为R生成环境。

我们可以展示profileFn()在我们的运行示例中的工作,如下所示:

这个结果表明,evaluateCell()被调用的次数是之前的evaluateBoard()被调用次数的59倍,它被调用了5096次。这显著降低了运行时间和必须发现的组合搜索空间。1.1.3 将问题分解为多个任务

并行性依赖于将问题分解为多个独立的工作单元。琐碎的(或有时它称为朴素并行性)将每一个单独的工作单元视为完全相互独立的。在这个方案中,当正在处理一个工作单元或任务时,没有与其他计算任务相互作用或共享信息的计算需求,不论现在、之前或以后。

对于我们的数谜,常见的方法是将问题分为19个独立的任务,其中每个任务是放置不同编号的小薄板在板上的单元1位置上,任务是探索搜索空间,寻找一个源于单一小薄板起始位置的解。然而,这只给了我们一个19的最大并行度,意味着我们探索空间的速度最大可以达到串行的19倍。我们还需要考虑整体效率。每个起始位置都带来相同的计算量吗?总之,不是。因为我们使用深度优先算法,当它找到一个正确的解时会立即结束任务,相反,一个不正确的起始位置可能会导致更大的、变化的、不可避免的毫无结果的搜索空间。因此我们的任务不是均衡的,将需要完成不同计算量的计算工作。我们也无法预测哪项任务会消耗更长时间来计算,因为我们不知道哪个起始位置会导致正确的先验解。

非均衡的计算

这种情况多见于典型的大量实际问题,即我们在复杂的搜索空间中寻找一个最优或接近最优的解,例如,寻找最有效的路线和方法来环游一组目的地或规划最有效率利用人力和物力来安排一系列活动。非均衡计算是一个重要的问题,其中在所有计算完成前,我们完全承诺计算资源并有效地等待执行最慢的任务。与串行中的运行相比,这会降低我们的并行加速比(speed up),它也可能意味着计算资源在大量时间内是空闲的而不是在做有用的工作。

为了提高我们的总体效率和并行性的机会,我们将问题划分为许多较小的计算任务,我们将利用一个特定功能的谜题来显著减少总体搜索空间。

我们将产生板的第一行(顶部)的前3个小薄板,单元为1到3。我们预计这会给我们带来19×18×17=5814种小薄板组合。然而,这些组合中只有一部分的和为38。1+2+3与17+18+19显然是无效的。我们也可以消除镜像组合。例如,板的第一行1+18+19将产生一个等价的搜索空间19+18+1,因此我们只需要考虑其中之一。

这是函数generateTriples()的代码。你会注意到我们使用6个字符的字符串表示3个小薄板来简化镜像测试,这也恰好可以合理、简洁、高效地实现:

如果运行这段代码,它将产生90个不同的三元组,显著节省了超过5814个起始位置:

使用lapply()执行多个任务

既然我们有一个有效定义的板的起始位置,那么可以看看如何管理分布式计算任务的设置。我们从lapply()开始,这使我们可以测试任务执行并制订程序结构,为此我们可以做一个简单的替换来并行运行。

lapply()函数有两个参数。第一个是对象的列表,它作为用户定义函数的输入;第二个是可调用的用户定义函数,每次对于每个单独的输入对象,它会返回每个函数调用的结果集合(作为一个单独的列表)。我们将重新打包求解程序,使它更容易与lapply()一起使用,求解程序包含迄今为止在整体solver()函数中我们开发的多种函数和数据结构,如下所示(求解程序的完整代码可以在本书的网站上获取):

让我们选择4个三元组小薄板来运行求解程序:

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载