Posted by carcassi
on January 24, 2007 at 10:24 PM PST
The latest addition to my bag tricks for HPC Java: runtime compilation of a Domain Specific Language expressions.
One area in which Java has an advantage over typical HPC languages
(C/C++/Fortran) is its ability to use information at runtime to fine tune the
code. If used well, this allows you to write code that is a bit more general without
sacrificing performance, as the code will get "re-specialized" at runtime.
While in C/C++ sometimes you are stuck with macros or preprocessing scripts, in Java I have been
finding a few different techniques. The last few nights I have been working on another one: runtime compilation of Domain Specific Language expressions.
As much as I'd like to show the actual code, it wouldn't really fit in a blog
entry... But the code is in the Jabble CVS repository, so I'll provide links
here and there for the curious reader. The flow is something like this:
developer/user specifies at runtime a String that represents
an expression like
where phi[x,y] is the field 'phi' at the offset from the current point (The above
expression is a second order derivative).
the String is passed to an ANTLR
generated parser , which return the
Abstract Syntax Tree
the AST is passed to an
expression builder , which creates a Jabble
specific tree that is able to calculate the expression at runtime, and aids
the Java source creation
the expression tree is transformed to
a String that represents a Java
class that makes that same computation. The Java class will implement the FiniteExpression interface.
the java source is
passed to the JSR199 compiler , which returns a binary
representation of the bytecode
the bytecode is given to a
memory ClassLoader , so that it can be
accessed by the running JVM.
the ClassLoader is used to create an instance of the newly compiled
class, which will be handled as a FiniteExpression type object.
In short: at runtime you can quickly specify an expression (in your code or
through a UI), which gets compiled to Java code, and which is going to take
advantage of all of the Java optimizations. To give you the picture: the calls
made by the runtime generated code are going to be inlined!
There are other, even more interesting possibilities. Given that I have the
domain model expression, I can provide functionalities and optimizations that
are specific to it. For example, I can simplify the expression; I can also
determine the order in which to compute the different fields. (For example, I
can easily understand that "beta[0,0] = alpha[1,0] - 2 * alpha[0,0] +
alpha[-1,0]" has to be calculated before and in a different Grid iteration than
"gamma[0,0] = beta[1,0] - beta[-1,0] + alpha[0,0]")
The only catch? I have to wait for JDK6 to be available on a Mac to add this
to a Jabble release...