Java for High Performance Computing
Introduction to Java for HPC
http://www.hpjava.org/courses/arl
Instructor: Bryan Carpenter
Pervasive Technology Labs
Indiana University
[email protected]
1
Java History

The Java language grabbed public attention in 1995, with the
release of the HotJava experimental Web browser, and the
subsequent incorporation of Java into the Netscape browser.
– Java had originally been developed—under the name of Oak—as an
operating environment for PDAs, a few years before.

Very suddenly, Java became one of the most important
programming languages in the industry.
– The trend continued. Although Web applets proved less important than they
originally seemed, Java was rapidly adopted by many other sectors of the
programming community.

Within a year or so of its release, some people were suggesting that
Java might be good for high performance scientific computing.
– A workshop on Java for Science and Engineering Computation was held at
Syracuse University in late 1996—a precursor of the subsequent Java
Grande activities.
[email protected]
2
Why Java for HPC?

Many people believed that in general Java provided a better
programming platform than its precursors, and in particular
that it was better adapted to the Internet.
– In the parallel computing world there has been a long history of novel
language concepts to support parallelism, multithreading etc.
– Java seemed to incorporate at least some of these ideas, and it had the
benefit that it was clearly going to be a mainstream language.


Essentially this analysis stands. The most likely reason for
doing scientific computing in Java is that in general it
encourages better software engineering than, say, Fortran, and
there is a huge amount of excellent supporting software for
Java.
But in 1996 there was a obvious blot on this landscape:
performance.
[email protected]
3
Preamble: High Performance?
[email protected]
4
The Java Virtual Machine


Java programs are not compiled to machine code in the same way
as conventional programming language.
To support safe execution of compiled code on multiple platforms
(portability, security), they are compiled to instructions for an
abstract machine called the Java Virtual Machine (JVM).
– The JVM is a specification originally published by Sun Microsystems.
– JVM instructions are called Java byte codes. They are stored in a class file.
– The JVM is a program that runs on a “real” computer. So any compiled Java
program (class file) can be run on any computer that has a JVM available.
– This execution model is part of the specification of the Java platform. There
are a few compilers from the Java language to machine code, but it is hard to
get these recognized as “Java compliant”.

The first implementations of the JVM simply interpreted the byte
codes. These implementations were very slow.
– This led to a common misconception that Java is an interpreted language and
inherently slow.
[email protected]
5
Run-time Compilation




Modern JVMs normally perform some form of compilation from byte
codes to machine code on the fly, as the Java program is executed.
In one form of Just-In-Time compilation, methods may be compiled to
machine code immediately before they are executed for the first time.
Then subsequent calls to the method just involve jumping into the machine
code.
More sophisticated forms of adaptive compilation (like in the Sun Hotspot
JVMs) initially run methods in interpreted mode, monitor program
behavior, and only spend time compiling portions of the byte code where
the program spends significant time. This allows more intelligent
allocation of CPU time to compilation and optimization.
Modern JVMs (like the Hotspot server JVM) implement many of the most
important kinds of optimization in used by static compilers for
“traditional” programming languages.
– Adaptive compilation may also allow some optimization approaches that are
impractical for static compilers, because they don’t have the run-time
information.
[email protected]
6
Java Grande Forum


An early stimulus for adoption of Java technologies in large
scale computation—especially scientific and technical—was
the Java Grande Forum.
The Java Grande Forum (www.javagrande.org) met and held
annual ACM conferences between 1997 and 2002.
– Related workshops held in Melbourne and Nice this year (2003).


They proposed various improvements to Java for numerical
and large scale computing, some of which were adopted into
Java platform.
The Forum was divided into a Concurrency and Applications
Working Group and a Numerics Working Group
(http://math.nist.gov/javanumerics).
– Later also spawned a Message Passing Working Group
(https://mailer.csit.fsu.edu/mailman/listinfo/java-mpi) and a
Benchmarking Activity (www.epcc.ed.ac.uk/javagrande).
[email protected]
7
Numerics Working Group

Activities of the JG Numerics Working Group have embraced
various issues related to numeric computation in Java:
– Basic floating point semantics of the Java language—had an early
success when their proposed strictfp modifier was adopted into the
Java 2 language.
– Libraries to support multidimensional arrays, complex arithmetic,
linear algebra, higher transcendental functions.
– Discussed language extensions, notably for multiarrays and complex
numbers (also operator overloading, etc).
– Produced two JSRs (Java Specification Requests) to the Java
Community Process
» One of them (Numeric Extensions) was withdrawn last year. The other
(Multiarray Package) is still on the table.

Led by Ron Boisvert and Roldan Pozo of NIST.
http://math.nist.gov/javanumerics
[email protected]
8
Message Passing Working Group

The JG Message Passing Working Group met between 1998
and 1999, largely to address the gap left by the absence of any
“official” binding for Java from the MPI forum.
– The working group had representation from various teams responsible
for early MPI-like systems for Java.
– Led by Vladimir Getov.
– A specification was published in:
MPJ: MPI-like message passing for Java
B. Carpenter, V. Getov, G. Judd, A. Skjellum, G. Fox
Concurrency Practice and Experience, 12(11), 2000.
– mpiJava was nominated as a “reference implementation” by the Java
Grande Working group.
[email protected]
9
Benchmarking Activity

Edinburgh University led a Benchmarking Activity in JG, and assembled
a suite of (mainly) scientific benchmarks for Java:
www.epcc.ed.ac.uk/javagrande

The suite is divided into 4 parts:
1. Sequential benchmarks, suitable for single processor execution.
–
Subdivided into low-level operations, kernels (7 basic algorithms), and 5 “large
scale applications”.
2. multi-threaded benchmarks, suitable for parallel execution on shared
memory multiprocessors.
–
Low-level thread benchmarks, and a parallel subset of the kernels and
applications above.
3. MPJ benchmarks, suitable for parallel execution on distributed memory
multiprocessors.
–
Low-level benchmarks for MPI-like primitives, and a parallelized subset of the
kernels and applications above (developed using mpiJava).
4. Language comparison benchmarks, which are a subset of the sequential
benchmarks translated into C.

Various results presented at Java Grande/ISCOPE 2001 conference…
[email protected]
10
Benchmarking Java against C and Fortran

In a widely cited paper:
“Benchmarking Java against C and Fortran for Scientific Applications”
ACM Java Grande/ISCOPE 2001 Conference

J. M. Bull, L. A. Smith, L. Pottage and R. Freeman presented
evidence that Java performance was becoming competitive with
C and Fortran.
They compared a subset of the kernel and application
benchmarks from the JG benchmark suite against C and Fortran
versions, using a variety of JVM implementations and native
compilers, on four platforms:
–
–
–
–
Intel Pentium, Windows (NT)
Intel Pentium, Linux
Sun Ultrasparc
Compaq Alpha
[email protected]
11
Tested Platforms and Compilers
[email protected]
12
Example Timings (Kernels)
[email protected]
13
Example Timings (Applications)
[email protected]
14
All Results
[email protected]
15
Mean Execution Time Ratios
[email protected]
16
Remarks

Comparisons with C and C++ are generally very satisfactory,
especially on the important Pentium platforms.
– On Linux the IBM JDK 1.3 generally does best (except on MolDyn
for some reason).
– We usually use this JDK for our own benchmarks.


Java also compares favorably with g77 (GNU Fortran).
Comparisons with Portland Group Fortran on Linux are more
troublesome.
– pg77 is more than twice as fast as the best Java on MolDyn.
– Comparison is more favorable on LUFact, but this code has been
criticized by other authors.
– Unfortunately there aren’t more Fortran results.
– Of course the Portland compiler is highly tuned for scientific
algorithms.
[email protected]
17
NAS Parallel Benchmarks

For balance, see the less rosy view of Java performance reported in
“Implementation of the NAS Parallel Benchmarks in Java”,
Michael A. Frumkin, Matthew Schultz, Haoqiang Jin, and Jerry Yan,
NAS Technical Report NAS-02-009.
– Presented at IPDPS 2003, Nice, France

The translate the NAS benchmarks to Java, and study performance
on various platforms: IBM p690, SGI Origin2000, Sun
Enterprise10000, Linux PC, Apple Xserve.
– Where they give Fortran results (only reported for IBM and SGI platforms),
differences in performance are as much as an order of magnitude.
– Unfortunately they emphasize SGI (not generally considered a good platform
for Java), and don’t give Fortran results for the “commodity platforms”.
– Their results for the IBM platform are intermediate—performance ratios of 3
or 4 typical (less for some benchmarks)?
[email protected]
18
What I Think is the Situation


On Linux platforms (which of course are widely used for clusters), if you
use the “free” compilers for C and Fortran (like gcc, g77), and if you use a
good JVM like the one in the free IBM JDK, performance of Java, C, and
Fortran are quite similar.
On the same platforms, if you use a proprietary Fortran compiler like the
one from Portland, you will probably still see a significant speed
advantage for Fortran.
– The Edinburgh results suggest factors 2-3, but with extremely limited
statistics!

On IBM platforms (where they have good Fortran compilers) a factor
around 4 is probably still common.
– And apparently there are still cases, like on the SGI, where an order of
magnitude is common.

This is just my reading of the situation based on the few published
benchmarks, plus our own experiences. It would be good to have a lot
more data on this!
[email protected]
19
Features of the Java Language
[email protected]
20
Prerequisites

We assume you know either Java or C++ moderately well.
– But some things, like threaded programming with Java and RMI, will
be covered from an introductory level.

In this section I will only point out some features and
terminologies are characteristic of Java and that you probably
should understand.
– And highlight some of the differences from C++.
[email protected]
21
What Java Isn’t

Perhaps the main thing it isn’t is C++—after programming Java it for a long time,
it’s hard to think of it as being very closely related to C++.
– It has a similar syntax for expressions, control constructs, etc, but those are perhaps the
least characteristic features of C++.
– The mindset when you are programming Java is very different:

In C++ you use characteristic features like operator overloading, copy constructors,
templates, etc, to create your own “little language”, as you write class libraries.
– You often spend a lot of time worrying about memory management and efficient creation
of objects.
– Worry about inline versus virtual methods, pointers and references, minimizing
overheads.

In Java most of these things features go away.
– Minimal control over memory management, due to automatic garbage collection.
– Highly dynamic language: all code is loaded dynamically on demand; implicit run-time
descriptors play an important role, through run-time type checks, instanceof, etc.
– Logically all methods are virtual; overloading and implementation of interfaces is
ubiquitous.
– Exceptions, rarely used in C++, are used universally in Java.
[email protected]
22
Class Structure

In Java, all methods and non-local variables are explicitly
member of classes (or interfaces).
– No default, global, namespace (except the names of classes and
interfaces).

Java discards multiple inheritance at the class level.
Inheritance relations between classes are strictly tree-like.
– Every class inheritance diagram has the universal base class Object at
its root.

It introduces the important idea of an interface, which is
logically different from a class. Interfaces contain no
implementation code for the methods they define.
– Multiple inheritance of interfaces is allowed, and this is how Java
manages without it at the class level.

Since Java 1.2, classes and interfaces can be nested. This is a
big change.
[email protected]
23
Classes and Instances

Will consistently use the following terminologies (which are
“correct”):
– A class is a type, e.g.
public class A {int x ; void foo() {}}
– An interface is a type.
– An instance is an object. An object is always an instance of one
particular class.
» That class may extend other classes and implement various interfaces.
– Any expression in Java that has class type (or interface type) is a
reference to some instance (or it is a null reference). E.g. a variable
declared:
Aa;
holds a reference to an instance. The objects themselves are “behind
the scenes” in Java: we can only manipulate pointers to them.
» Also references to objects and arrays are the only kinds of pointer in Java.
E.g. there are no pointers to fields or array elements or local variables.
[email protected]
24
Instance and static members

The following terminologies are common. In:
public class A {
int x
void foo() {…}
static int y ;
static void goo() {…}
}
We say:
x is an or instance variable, or non-static field.
foo() is an instance method, or non-static method.
y is a static field, or class variable.
goo() is a static method, or class method.
[email protected]
25
Class Loading

A Java program is typically written as a class with a public, static, void, main()
method, as follows
public class MyProgram {
public static void main(String [] args) {
… body of program …
}
}
and started by a command like:
$ java MyProgram

What this command does is to create a Java Virtual Machine, load the class
MyProgram into that JVM, then invoke the main() method of the class (which
must have exactly the signature shown above).
– It finds the class file for MyProgram (usually called MyProgram.class) by searching
a list of directories, typically defined in the environment variable CLASSPATH.

As this process unfolds, dependencies on other class and interfaces and their
supertypes will be encountered, e.g. through statements that use other classes.
The class loader brings in the class files for these types on demand. Code is
loaded, and methods linked, incrementally throughout execution.
[email protected]
26
The CLASSPATH

Many people have problems getting the CLASSPATH
environment variable right.
– Because all linking is done at run-time, must ensure that this
environment variable has the right class files on it.
– There is a useful property called binary-compatibility between classes.
This means that (within some specified limits) two class files that
implement the same public interface can be used interchangeably. It
also means that if you pick up an inappropriate implementation of a
given class from the CLASSPATH at runtime, things can go wrong in
an opaque way.

The class path is a colon-separated (semicolon-separated in
Windows) list of directories and jar files.
– If the class path is empty, it is equivalent to “.”. But if the class path is
not empty, “.” is not included by default.
– A directory entry means a root directory in which class files or
package directories are stored; a jar entry means a jar archive in which
class files or package directories are stored.
[email protected]
27
Java Native Interface

Some methods in a class may be declared as native methods,
e.g.:
class B {
public native long add(int [] nums) ;
}
Notice the method add() has the modifier native, and the
body of the method declaration is missing
– It is replaced by a semicolon, similar to abstract methods in interfaces,
etc. But in this case the method isn’t abstract.


The implementation of a native method will be given in
another language, typically C or C++ (we consider C).
Implementing native methods is quite involved.
– It isn’t clear that is such a bad thing—maybe it discourages casual use!
– In general there should be a very good reason for resorting to JNI.
[email protected]
28
Implementing Native Methods


The required naming conventions and parameter lists of the
native functions are fairly complicated. First compile the Java
class with the native methods, then run the command javah to
automatically generate C headers.
A generated file B.h contains a prototype like
JNIEXPORT jlong JNICALL Java_B_add (JNIEnv *, jobject,
jintArray);

Here JNIEXPORT and JNICALL are macros whose
expansion you don’t need to worry about (defined in standard
headers).
Next you create B.c, in which you #include “B.h”, and give
your definition for the function Java_B_add() .
[email protected]
29
A Definition of Java_B_add()
JNIEXPORT jlong JNICALL Java_B_add(JNIEnv * env, jobject this,
jintArray nums) {
jint *cnums ;
int i, n ;
jlong sum = 0 ;
n = (*env)->GetArrayLen(env, nums) ;
cnums = (*env)->GetIntArrayElements(env, nums, NULL) ;
for(i = 0 ; i < n ; i++)
sum += cnums [i] ;
return sum ;
}
[email protected]
30
Remarks

Several C types are defined in standard jni.h headers that are handles to
Java objects.
– JNIEnv represents (somehow) the Java environment in which the method was
invoked. This includes handles on the C data structures associated with the
implementation of the JVM itself, and thread context.
– jobject is a handle on a Java object (or the structure in the JVM that represents
an object). In particular the parameter jobject this refers to the instance on
which the method was called.
– jintArray naturally represents a Java int[] array.
 The functions GetArrayLen and GetIntArrayElements (actually function-


valued fields of the JNIEnv struct) are effectively accessor methods for
the jintArray handle.
jint, jlong are typedefs that most likely equate to just C int and long
(depending on native word lengths).
In a real native library you must be much more careful about trapping
error conditions and exceptions, otherwise you compromise the safety of
Java.
[email protected]
31
Linking



The file B.c is compiled, then linked into a shared object
library (or dynamic linked library in Windows).
This library must be in a directory where the JVM can find it
at run time (e.g. on the LD_LIBRARY_PATH).
If the library is called libB.so, the Java program must execute
System.loadLibrary(“B”) ;

to load the native library.
Finally Java program can call the add() method.
[email protected]
32
The Invocation API



JNI also provides a very powerful mechanism for going the
other way—calling from a C program into Java.
First the C program needs to create a JVM (initialize all the
data structures associated with a running JVM), which it does
with a suitable library call.
It ends up with a JNIEnv handle, which it can then use to call
all the JNI C functions for operating on Java objects, just like
those used from in a native method implementation.
– Like GetIntArrayElements, but actually there are similar functions to
do completely general things, like creating objects, calling methods on
them, and so on.

The standard java command works exactly this way—it uses
the JNI invocation API to create a JVM, and call the main()
method of the class specified on the command line.
[email protected]
33
The Rest of this Course

1.
Will cover three core topics:
Multithreaded and Shared-Memory Programming in Java
–
–
–
2.
Java RMI and RMI-Based Approaches for HPC
–
–
–
3.
Introduction to Java RMI.
High Performance implementations of RMI.
Special topic: JavaParty—remote objects in Java.
MPI-Based Approaches for Java
–
–
–

Java as a multithreaded language; Java thread synchronization primitives.
Java threads for Shared Memory parallel programming.
Special topic: JOMP—an OpenMP-like system for Java.
Survey of MPI-like systems for Java
Programming with mpiJava
Special topic: HPJava—a data parallel extension of Java.
As another special topic we include an Introduction to Java New I/O,
and if there is time may say something about Web Services, Grids, etc.
[email protected]
34
Descargar

CIS6930: Java Remote Method Invocation