在Java中顺序引入并发法则外文翻译资料

 2022-07-13 20:25:41

Open access under the Elsevier OA license.

Information Processing Letters 111 (2011) 129–134

Contents lists available at ScienceDirect

Information Processing Letters

www.elsevier.com/locate/ipl

Introducing concurrency in sequential Java via laws

Rafael Duarte, Alexandre Mota lowast;, Augusto Sampaio

Centro de Informaacute;tica, Universidade Federal de Pernambuco, Caixa Postal 7851, Recife, PE, Brazil

a r t i c l e i n f o

Article history:

Received 10 February 2010

Received in revised form 5 November 2010 Accepted 6 November 2010

Available online 10 November 2010 Communicated by J.L. Fiadeiro

Keywords:

Formal methods

Concurrency

Parallel processing

Performance evaluation

Program correctness

a b s t r a c t

Nowadays multi-core processors can be found everywhere. It is well known that one way of improving performance is by parallelization. In this paper we propose a parallelization strategy for Java using algebraic laws. We perform an experiment with two benchmarks and show that our strategy produces a gain similar to a specialized parallel version

provided by the Java Grande Benchmark (JGB).

copy; 2010 Elsevier B.V.

1. Introduction

To explore multiple processing capabilities, software must be multi-threaded. A parallelization mechanism can be a solution. The idea is to hide the parallelism from the developer by providing either an automatic process or high-level abstractions. This involves generating a parallel version of a given sequential program, with minor or no human interference, which can be more cost-effective and safe than explicit parallelism, where human interference is intensive.

Java is an interesting language to explore parallelism. Recent surveys show that it is one of the most popular languages today that supports parallel programming with built-in threads, and has already proved its capabilities in different domains, such as web applications and even sci-entific computing [1].

Works reported in [2–6] propose ways to explore im-plicit parallelism in Java. They are carried out either at the bytecode or at the source code level. A common as-pect shared among them is the presence of extra code

* Corresponding author.

E-mail addresses: rmd@cin.ufpe.br (R. Duarte), acm@cin.ufpe.br (A. Mota), acas@cin.ufpe.br (A. Sampaio).

0020-0190 copy; 2010 Elsevier B.V. Open access under the Elsevier OA license. doi:10.1016/j.ipl.2010.11.004

introduced in the application either manually or by run-time tools. They provide good performance results, but they explore the parallelization in a very pragmatic way, without focusing on the correctness of the transformations. A promising approach is the use of algebraic laws, which provide insight on the algebraic semantics of languages, and are also used as a basis for the definition of reliable refactorings [7].

In this paper we propose a parallelization strategy for Java using algebraic laws that transforms an original se-quential program, introducing concurrency wherever pos-sible. The new program can explore a parallel architecture more easily, aiming at improving its original execution per-formance.

To evaluate our strategy, we perform two real-world case studies extracted from the Java Grande Benchmark suite (JGB) [8]. In both case studies we obtained equivalent average speedups of the parallel version created by hand.

Although we do not provide formal proofs for our laws, each case study used the benchmark validation mechanism to give some confidence that the transformations preserve semantic behavior. Our main contributions reported here are: (i) A novel lightweight and safety focused strategy to Java parallelization; (ii) Experiments assessing its competi-tiveness.

130 R. Duarte et al. / Information Processing Letters 111 (2011) 129–134

2. Laws

We present only laws related to parallelization. The en-tire catalog that supports the strategy can be found in [9]. The laws are written in Java, adopting the convention that a Java system has the form cds Main, where cds is a set of class declarations and Main is a class with the only main method present in the system.1

A condition required by a law is marked with (harr;) when it must hold in both transformation directions, or with () or (larr;), when it must hold only in the indicated direction.

2.1. Parallelization laws

These laws are responsible to rewrite a sequential into a parallel Java program. They rely on the notion of in-dependent commands, detectable by static (conservative) dependence analysis. This can diminish the cases where independent commands will be detected, but it will also reduce the analysis overhead.

As our focus is not on dependence analysis, we abstract details and simply use the predicate indep(stmt1, . . . , stmtk) to indicate that these k statements are independent; that is, they cannot share variables, direct or indirectly (via aliasing), unless the variables are read-only.

Our first law changes the order of commands, group-ing related commands to be run in different threads. It requir

全文共22025字,剩余内容已隐藏,支付完成后下载完整资料


在Java中顺序引入并发法则

拉斐尔杜阿尔特,亚历山大莫塔*,奥古斯托桑帕约

中央信息系统,联邦德伯南布科,邮政储蓄银行7851,累西腓,秘鲁,巴西

文章信息

文章历史:

2010年2月10日收到

2010年11月5日收到的修订表格于2010年11月6日接受。

2010年11月10日,J.L. 菲亚代罗在网上交流

关键词:

形式化方法

并发

并行处理

绩效评价

程序的正确性

摘要

现在到处都能找到多核处理器。众所周知,提高性能的一种方法是并行化。本文提出了用代数法java并行化策略。我们用两个基准进行了一次实验,结果表明我们的策略产生了类似于一个专门的并行版本的增益。

由Java Grande Benchmark(JGB)提供。

2010爱思维尔B.V.根据爱思维尔OA许可证打开访问权限

  1. 引言

要探索多个处理能力,软件必须是多线程的。并行化机制可以是一种解决方案。这个想法是通过提供自动过程或高级抽象来隐藏开发人员的并行性。这涉及到生成一个给定的串行程序的并行版本,具有较小或没有人为干扰,比人工并行性更具成本效益和安全性,其中人为干扰是密集的。

Java是探索并行性的有趣语言。最近的调查显示,它是当今最受欢迎的语言之一,它支持内置线程的并行编程,并且已经证明了它在不同领域的能力,比如web应用程序,甚至是科学计算[1]。

在[2-6]中报告的工作提出了在Java中探索一种复杂的并行性的方法。它们在字节码或源代码级别执行。在它们之间共享的一种常见的方法是在应用程序中手动或通过运行时工具引入额外的代码。它们提供了良好的性能结果,但是它们以非常实用的方式探索并行化,而不关注转换的正确性。一个有希望的方法是使用代数法,它提供了关于语言的代数语义的见解,也被用作可靠重构的定义的基础[7]。

在本文中,我们提出了一种使用代数法则的Java并行化策略,它可以转换原始的顺序程序,在任何可能的地方引入并发。新程序可以更轻松地探索并行体系结构,旨在提高其原始执行性能。

为了评估我们的战略,我们执行了两个从Java Grande Benchmark套件(JGB)[8]中提取的实际案例研究。在这两种情况的研究得到了手工创建的并行版本的等效平均速度。

虽然我们没有为我们的法则提供正式的证明,但是每一个案例研究都使用了基准验证机制来保证转换保持语义行为。我们的主要贡献是:(一)报道一种新的轻量级的安全策略对java并行化;(二)实验评估其竞争力。

  1. 法则

我们只介绍与并行化相关的法律。 支持该策略的en-tire目录可以在[9]中找到。这些法则是用Java编写的,采用Java系统具有cds Main形式的约定,其中cds是一组类的声明,Main是具有唯一主要方法的类。

由法则规定的条件有(harr;)时,必须持有两方向转化,或有(→)或(larr;)时,必须只能在指定的方向转化。

2.1. 并行化的法则

这些法则负责将顺序改写成并行Java程序。它们依赖于依赖命令的概念,可以通过静态(保守)依赖分析来检测。这可以减少检测到独立命令的情况,但也会减少分析开销。

由于我们关注的不是依赖分析,因此我们抽象详细信息,并简单地使用谓词indep(stmt1,...,stmtk)来表示这些k语句是独立的;也就是说,它们不能直接或间接(通过别名)共享变量,除非变量是只读的。

我们的第一个法则改变了命令的顺序,在不同的线程中运行组相关的命令。它要求命令是独立的。符号cd, cmd是指cmd是A类中的一个命令,并且在类声明cd的上下文中是良好的。

法则1(更改命令顺序)。如果是cds,A cmds1; cmds2然后是cds,A cmd1; cmd2 = cmd2;CMD1

前提:(harr;)indep(cmd1,cmd2)。

在其体内具有独立命令的循环可以被分解成两个循环,增加在不同线程中执行它们的机会。满足这些条件的循环通常包含固定数量的迭代。

法则2(分解循环)。

前提:(→)indep(cmd1,cmd2,cond)。

另一种可能性是条件是两个其他条件的结合,每个条件只受命令分区的影响。我们可以通过数据细化来分解循环,这样每个新循环都包含相关的命令和条件。

法则3(分割循环迭代)。

前提: (→) (1) forall;i, j | K i lt; F and; K j lt; F and; i = j bull; indep(cmdsi , cmds j ); (2) indep(cmdsi , cond); (3) K lt; J lt; F ;

(4) multiple( J , inc).

以前的法则旨在重构未来并行化的代码。下一个法则规定了同时执行命令所需的转换。要谨慎地引入并发执行,法律将在独立线程中执行原始命令cmds1,但在执行以下命令之前,会引入对join方法的调用,该方法会阻止执行,直到线程完成。这样,我们保持原有的顺序流程。该法捕获了在Java应用程序中引入线程的最简单方法。

法则4(分叉加入)。 如果是cds,A cmds1; cmds2然后是cds,A。

前提:(→)在cmds1内访问的外部变量被声明为final。

当方法join引发检查异常In-terruptedException时,我们必须解决这个异常。我们决定捕捉并忽略它,因为当另一个线程中断了我们正在等待完成的那个线程时抛出异常,在我们的例子中,我们控制线程的执行。因此我们确保没有其他线程会尝试中断它。

另外还有一个限制,特别是Java,它禁止在内部类中的方法中访问非最终变量。将最终修饰符添加到局部变量可防止它被多次分配。实际上,这个限制主要影响基本类型,因为当使用引用类型时,即使引用变量声明为final,我们也可以更改它们的属性值。

尽管如此,如果我们保持顺序执行,我们不能利用多个处理器。更重要的是,第4号法则在单独应用时会加剧程序性能。为了同时执行和提高性能,我们可以将方法连接进一步移到独立于线程执行的命令之后。以这种方式,我们可以更好地探索命令的并行执行。在下面的法则中,cmdst是指由t执行的命令。

法则5(移动连接)。如果是cds,A t:T hread,cmds则是cds,A。

前提:(harr;)indep(cmds,cmdst)。

只要有独立的命令,我们就可以继续移动方法连接。如果它成为main方法中的最后一个命令,那么它可以被删除,因为没有更多的命令要执行,因此没有等待t完成的命令。

法则6(消除连接)。

当对方法连接的调用被消除时,这意味着t与所有后续的命令无关。在这种情况下,t可以并行执行而不需要任何外部控制。

2.2. 正常形式和减少策略

在应用先前的法律之前,我们需要使用符合以下条件的还原策略将原始源代码转换为正常形式。

bull;cdsinternal中的每个类声明(Object除外)都没有属性;

bull;方法只允许在Main类中使用,并且它们必须是静态的;

bull;Main类有一个主要方法;

bull;Object类可能只包含属性声明,并且它们的类型必须是基本类型或Object,或者由外部类定义;

bull;主方法中的所有局部声明都使用原始类型,对象或外部类声明;

bull;在主要方法中不允许进行类型转换;

bull;没有构造函数的声明。

通过使用[7,9]详述的缩减策略,可以为任意的Java程序获得这种正常形式。这种减少策略的主要步骤是。

1.引入一个名为Object的新类,并更改类的层次结构,以使用Object作为新的超类。之后,每个属性都将其可见性更改为public,并将其从子类移到超类,直到它们到达超类_Object;

2.在调用内联后,消除所有构造函数声明和调用,包括通过super和this进行的调用;

3.每种方法声明都是通过依次应用法律来改变方法对公众的可见性,并引入三种重新定义,从而将其移至超级根对象。在那之后,我们消除了对超级方法的调用,并且引入了微不足道的强制转换;

最后,除了递归方法外,每个方法调用都被内联,并且方法声明被消除。

2.3. 并行化战略

与2.2节类似,并且在程序恢复到正常形式之后,我们需要应用并行化策略,在可能的情况下采用并发策略,2使用第2.1节的法律。

我们的策略可以分为两个主要步骤。第一个旨在重组源代码,使其更适合并行化。这由法律1,2和3执行。此后,在第二步中,法律4,5和6用于并行执行独立命令。

图1 源代码eval(a)方法之前和之后(b)的并行化

我们用一个简单的例子来概述我们的并行化策略。为了节省空间,我们从图1(a)的普通表格代码开始。如前所述,第一步是重新组织代码,分组相关的命令和分割循环。在这种情况下,没有循环,但是我们可以使用定律1对命令重新排序。这条定律反复使用,直到所有相关的命令组合在一起。

重新排序后,我们现在可以应用法则并行执行命令。在eval方法中,有两块独立的命令,每一块都负责评估表达式的一边。另外,他们后面跟着一个使用他们结果的命令。这个场景表明了法则4.但是对于它的条件来说,我们必须把最终的修饰符加到局部变量lint,rint,le和re([9]中的定律)。然后我们使用Law 5来调用join,直到取决于线程的命令为止。

现在,对表达式的每一边的评估都是由一个独立的线程执行的,并且顺序执行继续直到它们的计算结果是需要的。此时,在每个线程上调用的方法join,确保只有在完成后才能继续执行。重要的是要强调这个例子是为了说明这个策略。在这种情况下,由于并行执行的轻量级计算,并行化代码很难实现一些加速。最终结果如图1(b)所示。

从图1(b)我们可以看到,我们的策略不会改变源代码的结构。相反,它会改变方法体内的命令执行方式。请注意,在图1(a)中我们有一个完整的顺序代码,而在图1(b)中我们有一个有两个线程的代码。

  1. 案例研究

为了执行我们的案例研究,我们从选定的基准中获得了原始的顺序代码。在应用我们的策略之前,我们隔离了与基准相对应的代码。我们测量了为每个基准(A,B和C)提供的三种不同输入大小的执行时间。

在完成代码转换之后,我们将它们中的每一个关于它们的执行时间和行为保存进行比较。每个基准的执行时间由JGB(Java Grande Benchmark)提供的定时器获得。要计算执行时间数据,我们执行每个代码十次,计算它们的平均值(算术平均值),并在比较中使用此值。JGB还使用基于测试的验证机制来获得行为保护。

我们使用了英特尔酷睿i7 2.67 GHz桌面,具有8 GB的RAM,Ubuntu Linux(内核2.6.32-25)和Sun的JDK 1.6.0_22版本。我们在每个测试中设置相同的执行条件,以避免外部威胁的有效性。

3.1. 傅立叶级数

我们的第一个基准计算了0-2区间函数f(x)=(x 1)x的前10 000个傅立叶系数。在应用我们的策略之前,我们对原始类进行了一些小修改:删除所有包和导入子句,并删除一个实现子句(对我们的代码没有任何影响)。我们还考虑了两个实用程序类(JGFInstrumentor,JGFTimer)作为外部代码(仅编译代码)。

表1中显示的结果显示比原始顺序版本显着加速,比JGB的并行版本略高。这真是一个惊喜,因为手动编写的并行代码往往会更好地执行。此外,正常形式的代码比原始形式的性能稍好一些,提供了一些证据表明正常形式缩减策略不会产生执行开销。

表格1

每种输入大小(A,B和C)和并行版本(PV:具有2个和4个线程的建议版本,JGB:具有2个和4个线程的Java Grande并行版本)的案例研究加速。

3.2. IDEA加密

该基准测试对随机生成的300万字节的数组执行IDEA [10](国际数据加密算法)加密和解密算法。其代码结构与傅里叶基准相似,但一些实现细节阻碍了我们的策略的使用。除了像前面的案例研究中所做的那样去除包和实现子句之外,我们还必须对算法进行小幅改动,将外部变量移动到循环中。除此之外,我们的规范化和并行化策略涵盖了所有转换。

在这种情况下,我们的方法为JGB的并行版本提供了等同的加速。在执行A尺寸基准时,我们只注意到一个意外的行为。在这种情况下,加速比预期更低,并且4线程版本没有比2线程版本显着加速。我们认为这是由于输入大小非常小,不足以弥补线程创建的开销。这个问题在JGB的版本中没有发生,因为线程创建在代码中被人为调节。关于正常形式的版本,它与前面的案例研究类似。

  1. 相关工作

并行化Java程序有一些工作,如[11,12,5,4,3,2]。Javar重组编译器[11]实现了旨在并行化Java代码的源代码转换。为了检测代码的哪些部分将被并行化,它依赖于用户注释。在文献[12]中,作者关注循环的自动并行化,获得原始代码的显着加速。并行化在编译时自动执行,由作者开发的特定编译器自动执行。

Java程序在[5]的字节码级别被并行化。这种方法的结果非常好,即使没有源代码可用,也可以应用。然而,它的主要缺点是它使用了处理器特定的优化,限制了它的实际使用。在[4,3]并行化方法调用中介绍的方法

全文共7355字,剩余内容已隐藏,支付完成后下载完整资料


资料编号:[9556],资料为PDF文档或Word文档,PDF文档可免费转换为Word

原文和译文剩余内容已隐藏,您需要先支付 30元 才能查看原文和译文全部内容!立即支付

以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。