Java Communications for High-End Applications

Bryan Carpenter(?), Vladimir Getov, Gregor von Laszewski, Michael Philippsen

September 8, 2000

1 Introduction

Our proposed idea for this paper is to cover the communications spectrum of Java systems - message passing, RMI, computer portals (Grid computing). It looks good to start with a discussion of the High-End applications (components, mixed-language, distributed, etc.) for scientific computing.

Cherri suggested we also discuss the trade-off between s/w development efforts and the efficiency. I guess this will require an overview of the corresponding programming models (SPMD, client/server, etc.)

Another area that we may want to cover relates to the main features of different communication paradigms such as symetry, polymorphism, interoperability, etc. Not sure about that - just thinking?

2 Message Passing in Java

The Java language has several built-in mechanisms which allow the parallelism inherent in scientific programs to be exploited. Threads and concurrency constructs are well-suited to shared memory computers, but not large-scale distributed memory machines. Although sockets and the RMI interface allow the development of big network applications, they have been designed and optimized for client-server programming, whereas the parallel computing world is mainly concerned with a more symmetric model, where communications occur in groups of interacting peers. Therefore, codes based on sockets and RMI would naturally underperform platform-specific implementations of standard communication libraries based on the successful Message Passing Interface (MPI) standard [1]. By contrast with sockets and RMI, MPI directly supports the Single Program Multiple Data (SPMD) model of parallel computing, wherein a group of processes cooperate by executing identical program images on local data values.

With the evident success of Java as a programming language, and its inevitable use in connection with parallel as well as distributed computing, the absence of a well-designed language-specific binding for message-passing with Java would lead to divergent, non-portable practices. The Message-Passing Working Group of the Java Grande Forum was formed in the Fall of 1998 as a response to the appearance of the various APIs for message-passing. Some of these early “proof-of-concept” implementations [2, 5, 4] have been available since 1997 with successful ports on clusters of workstations running Linux, Solaris, Windows NT, Irix, AIX, HP-UX, and MacOS, as well as on parallel platforms such as the IBM SP-2 and SP-3, Sun E4000, SGI Origin-2000, Fujitsu AP3000, Hitachi SR2201 and others. An immediate goal was to discuss and agree on a common API for MPI-like libraries for Message Passing in Java (MPJ) [3].

The MPI standard is explicitly object-based. The C and Fortran bindings rely on “opaque objects” that can be manipulated only by acquiring object handles from constructor functions, and passing the handles to suitable functions in the library. The C++ binding specified in the MPI-2 standard collects these objects into suitable class hierarchies and defines most of the library functions as class member functions. The MPJ API specification follows this model, lifting the structure of its class hierarchy directly from the C++ binding. The purpose of this phase of the effort is to provide an immediate, ad hoc standardization for common message passing programs in Java, as well as to provide a basis for conversion between C, C++, Fortran, and Java.

In this paper we present performance analysis and comparisons of evaluation results for both Java and C/Fortran on three different message-passing parallel platforms – a shared memory multiprocessor (Sun E4000), a Linux cluster, and a distributed memory computer (IBM SP-2). The NAS parallel Embarrassingly Parallel (EP) and the Integer Sort (IS) benchmarks were used in our performance evaluation. The IS routine evaluates integer operations and bi-directional communications (the sorted keys are exchanged between nodes), while the EP kernel tests floating point operations performance but requires minimal communications.

The JVM and the Java compiler used on the IBM SP-2 machine were part of the JDK for AIX. The execution environment consisted of IBM’s Parallel Operating Environment (POE), which supports the loading and execution of parallel processes across the nodes of the IBM SP-2. The machine is built of thin nodes with POWER2 Super Chip (P2SC) processors and 256 Mbytes of memory on each processor. The communication subsystem of the SP-2 features a high-performance switch which was used throughout the experiments. The NAS EP and IS benchmarks were also run on a 200 MHz dual Pentium Pro processor cluster running Linux Red Hat 6.0 on a 10baseT Ethernet. The same experiments were performed on a 14x336 MHz Ultra Sparc II processor Sun E4000 running Solaris 2.6. The LAM MPI library was used on the Linux cluster, whilst both the SP-2 and the E4000 provided native MPI libraries for message passing.

A native code compiler for Java can be used instead of the JVM in order to overcome the above problem. Fortunately, rapid progress is being made in this area by developing optimizing Java compilers, such as the IBM High-Performance Compiler for Java (HPCJ), which generates native codes for the RS6000 architecture [?]. It works in the same manner as compilers for C, C++, Fortran, etc. and unlike JIT compilers, the static compilation occurs only once, before execution time. Thus, traditional resource-intensive optimisations can be applied in order to improve the performance of the generated native executable code. In our experiments, we have used a version of HPCJ, which generates native code for the RS/6000 architecture. The input of HPCJ is usually a bytecode file, but the compiler will also accept Java source as input. In the latter case it invokes the JDK source-to-bytecode compiler to produce the bytecode file first. This file is then processed by a translator which passes an intermediate language representation to the common back-end from the family of compilers for the RS/6000 architecture. The back-end outputs standard object code which is then linked with other object modules and the previously bound legacy libraries to produce native executable code. Further experiments to evaluate the performance of the environment based

Figure 1: Execution times for the NPB EP kernel (class B) on the IBM SP-2

on HPCJ have been carried out with the IS kernel on an IBM SP-2 machine. The results obtained are shown in Figure 2.

Back in 1994, MPI-1 was originally designed with relatively static platforms in mind. To better support computing in volatile Internet environments, modern message passing designs for Java will have to support (at least) features such as dynamic spawning of process groups and parallel client/server interfaces as introduced in the MPI-2 specification. In addition, a natural framework for dynamically discovering new compute resources and establishing connections between running programs already exists in Sun’s Jini project [6], and one line of investigation is into MPJ implementations operating in the Jini framework.

Closely modelled as it is on the MPI standards, the existing MPJ specification should be regarded as a first phase in a broader program to define a more Java-centric high performance message-passing environment. In future a detachment from legacy implementations involving Java on top of native methods will be emphasized. We should consider the possibility of layering the messaging middleware over standard transports and other Java-compliant middleware (like CORBA). Of course, a primary goal in the above mentioned, both current and future work, should be the aim to offer MPI-like services to Java programs in an upward compatible fashion. The purposes are twofold: performance and portability.

Figure 2: Execution time for the NPB IS kernel (class A) on the IBM SP-2

3 Faster Remote Method Invocation

Good latency times and high bandwidths are essential for distributed and parallel programs. However, the remote method invocation (RMI) of common Java distributions is too slow for high performance applications, since RMI was developed for wide area networks, builds upon the slow object serialization, and does not support any high speed networks. With regular Java, a remote method invocation takes milliseconds – concrete times depend on the number and the types of arguments. A third of that time is needed for the RMI itself, a third for the serialization of the arguments (their transformation into a machine-independent byte representation), and a third for the data transfer (TCP/IP-Ethernet).

In order to achieve a fast remote method invocation, work must be done at all levels. This means that one needs a fast RMI implementation, a fast serialization, and the possibility of using communication hardware that does not employ TCP/IP protocols.

Within the framework of the JavaParty Project at the University of Karlsruhe [7], all three of these requirements were attacked to create the fastest (pure) Java implementation of a remote method invocation. On a cluster of DEC-Alpha computers connected by Myrinet, called ParaStation, currently a remote method invocation takes about 80 μs although it is completely implemented in Java.^{1} Figure 3 shows, that for benchmark programs 96% of the time can be saved, if the UKA serialization, the high-speed RMI (KaRMI), and the faster communication hardware is used. The central ideas of the optimization will be highlighted in the next sections.

1Of course, the connection of the card driver was not realized in Java.

Figure 3: The bottom three box plots each show 2·64 measured results for diverse benchmarks (64 points represent Ethernet on PC, 64 stand for FastEthernet on Alpha). The first (bottom-most) box plot shows the run-time improvement that was achieved with regular RMI and the UKA serialization. The second box plot shows the improvement that KaRMI achieves when used with Java’s regular serialization. The third box plot shows the combined effect. The top line demonstrates what happens, if Myrinet cards are used in addition to the UKA serialization and KaRMI (64 measured results).

3.1 UKA Serialization.

The UKA serialization [10] can be used instead of the official serialization (and as a supplement to it) and saves 76%–96% of the serialization time. It is based on the following main points:

• Explicit serialization routines (“marshalling routines”) are faster than those used by classical RMI that automatically derive a byte representation with the help of type introspection.

• A good deal of the costs of the serialization are needed for the time-consuming encoding of the type information that is necessary for persistent object storage. For the purposes of communication, especially in work station clusters with common file systems, a reduced form of the type encoding is sufficient and faster. The Java Grande Forum has convinced Sun Microsystems to make the method of type encoding plugable in one of the next versions.

• Copied objects need to be transferred again for each call in RMI. RMI does not differentiate between type encoding and useful data, meaning that the type information is transferred redundantly.

• Sun has announced (without concretely naming a version) it will pick up on the idea of a separate reset of type information and user data.

• The official serialization uses several layers of streams that all possess their own buffers. This causes frequent copying operations and results in unacceptable performance. The UKA serialization only needs one buffer, which the byte representation can be directly written in.

• Although Sun remains steadfast about layering for reasons of clearer object-oriented design, they are at least improving the implementation of the layers.

3.2 KaRMI.

A substitute implementation of RMI, called KaRMI, was also created at the University of Karlsruhe. KaRMI [9] can be used instead of the official RMI and gets rid of the following deficiencies, as well as some others found in official RMI:

• KaRMI supports non-TCP/IP networks. Suns plans to add support in the official RMI-Version as well.

• KaRMI possesses clearer layering, which will make it easier to employ other protocol semantics (i.e. Multicast) and other network hardware (i.e. Myrinet-Cards).

• In RMI, objects can be connected to fixed port numbers. Therefore, a certain detail of the network layer is passed to the application. Since this is in conflict with the guidelines of modular design, KaRMI only supports use of explicit port numbers when the underlying network offers them.

• The distributed garbage collection of the official RMI was created for wide area networks. Although there are optimized garbage collectors for tightly coupled clusters and for other platforms [8], the official RMI sees no alternative garbage collector as being necessary, in contrast to KaRMI.

4 Gregor’s stuff

5 Conclusions

References

[1] Message Passing Interface Forum. MPI: A message-passing interface standard. International Journal of Supercomputer Applications, 8(3/4), 1994.

[2] http://www.npac.syr.edu/projects/pcrc/HPJava/.

[3] B. Carpenter, V. Getov, G. Judd, A. Skjellum, and G. Fox. MPJ: MPI-like Message Passing for Java. Concurrency: Practice and Experience, 12, 2000 (to appear).

[4] Glenn Judd, Mark Clement, Quinn Snell, and Vladimir Getov. Design issues for efficient implementation of MPI in Java. In ACM 1999 Java Grande Conference, pages 58–65, San Francisco, June 12–14, 1999.

[5] S. Mintchev and V. Getov. Towards portable message passing in Java: Binding MPI. In M. Bubak, J. Dongarra, and J. Wańiewski, editors, Recent Advances in PVM and MPI, Lecture Notes in Computer Science, pages 135–142. Springer Verlag, 1997.

[6] Ken Arnold, Bryan O’Sullivan, Robert Scheifler, Jim Waldo, and Ann Wollrath. The Jini Specification. Addison Wesley, 1999.

[7] JavaParty. http://wwwipd.ira.uka.de/JavaParty/.

[8] Michael Philippsen. Cooperating distributed garbage collectors for clusters and beyond. Concurrency: Practice and Experience, to appear, 2000.

[9] Michael Philippsen, Bernhard Haumacher, and Christian Nester. More efficient serialization and RMI for Java. Concurrency: Practice and Experience, to appear, 2000.

[10] Bernhard Haumacher and Michael Philippsen. More efficient object serialization. In Parallel and Distributed Processing, number 1586 in Lecture Notes in Computer Science, Puerto Rico, April 12, 1999. Springer Verlag.

A Sidebar on Java Portability

1. Source Code

2. Byte Code

3. Data Format

4. Output Results (Reproducibility)

5. Performance

6. Executable Code