A Prototype Computational Fluid Dynamics Case Study in Java^{T M}

Christopher A. Atwood, Rajat P. Garg, & Dennis DeRyke

              {Chris.Atwood, Rajat.Garg, Dennis.DeRyke}@Corp.Sun.COM

Market Development Engineering Sun Microsystems, Inc. 2550 Garcia Avenue, Mountain View, CA 94043

                                   www.sun.com

Abstract

Java^{T M} offers the benefits of portability, object orientation, graphical interface components, multithreading, and distributed programming capability. However, for numerically intensive technical applications, performance of non-native code can be critical. This effort evaluates the Java platform on the basis of code development capability and performance by contrasting several implementations of a transonic small disturbance equation solver. The use of the abstract windowing toolkit, native methods, and a client-server implementation are documented herein.

1 Introduction

The popularity of open network protocols has led to the proliferation of interconnected heterogeneous systems, with concomitant coding costs for cross-platform applications. In turn, this interconnection has focused attention on Java (see [1, 2] and references therein) as a solution to concerns of portability and security. Although Java has garnered widespread use for applets on the Web, several factors indicate that Java may also play a significant role in the engineering community.

Firstly, the portability of the language offers a means of reducing the cost of maintaining algorithms across platforms, freeing developers to create functionality. Secondly, the widespread adoption of Java by commercial developers has led to a competitive marketplace for tools, enabling development on low cost platforms and rapid deployment on high-performance systems. This availability and publishing ease has led to rapid adoption by faculty and students, thus generating a ready pool of developer talent.

Finally, the object orientation and threading interface of Java offers a means for wider code reuse, currently rare in the numerical community. Component reuse offers the potential for rapid distribution of new research algorithms and foreshortened development cycles in scientific software shops.

Despite the primary attribute of rapid code development, performance which lags statically compiled code remains a hindrance to the use of Java for numerically intensive applications. This effort will explore the use of this language for the development of a prototype engineering code, documenting Java, native, client-server, and graphical interface development. Secondly, this effort will also quantify the performance trends of Java versus native implementations for this field equation solver. The paper is organized as follows: we begin by breifly describing the numerical model in section 2, followed by an overview of various Java implementation models in section 3. A description of graphical post-processing is included in section 4 and benchmarking results are discussed in section 5. Finally, some conclusions are presented in section 6.

2 Numerical Model

The code used for this study solves the transonic small disturbance equation for simulation of inviscid steady transonic flow over slender bodies (see [3], [4]). Slender bodies only causes minor perturbations to the incoming flow and the inviscid two dimensional Euler equations can be simplified to a linear equation of the following form:

[1 − M_{∞}^{2} − (γ + 1)M_{∞}^{2} \frac{ϕ_{x}}{q_{∞}} ] ϕ_{xx} + ϕ_{yy} = 0,  (1)

where M_{∞} is the freestream Mach number, q_{∞} is the freestream velocity, ϕ is the disturbance potential and γ = (1.41) is the gas constant, respectively. The equations are solved subject to the following conditions

ϕ → 0  far from body i.e. x → ±∞, y → ∞
\frac{∂ϕ}{∂η} = 0 at body and Symmetry axis.  (2)

(3)

In above η is the local normal to the body.

In the present work, these equations are solved for a thin circular airfoil (aspect ratio = 0.06) using the classic Murman and Cole ([5]) algorithm. This approach utilizes a second order centraldifferencing scheme in subsonic regions of the flow and a first-order upwind-bised differencing in the supersonic regions for numerical stability. A Cartesian grid with equal spacing in the x direction over the body and geometric stretching on either side (the stretching factor was was determined by trial and error and varied between different runs) is used. A geometrically stretched mesh is also used in the y direction. The resulting linear system of algebraic equations is iteratively solved using a Gauss-Seidel line relaxation (GSLR) technique (see [5]); this involves sweeping in the streamwise direction and solution of a tridiagonal system of equations normal to the airfoil. initerations were used

3 Java Implementation Models

One of the main objectives of this study was to explore the usefulness of Java’s various programming paradigms for the present application. Accordingly, we evaluated several different models from the point of view of ease of implemenation, portability and attained performance. Following approaches were considered:

1. Fully Java – the entire solver was implemented in Java as a standalone object-oriented application. A certification that the code is 100% Java was obtained by running JavaPureCheck tool ([6]) on the compiled class files.

2. Java/C JNI – In order to gauge the performance degradation due to portability constraints, the method implementing the iterative solver was also coded in C. This solver procedure was called from the Java code using JNI, the Java Native Interface ([11]). The JNI is an implementation interface designed to integrate non-Java code (written in languages such as C etc.) with the Java code. The most common example of such a situation is in the reuse of existing (optimized) platform-dependent libraries with the Java code. The JNI is a new addition to JDK1.1 API and significantly improves upon the Native Methods Invocation (NMI) API in the JDK1.0.2 release.

3. Java RMI – Remote Methods Invocation (RMI) ([12, 13]) is the Java API for enabling integration of distributed objects in Java code. The objects reside in different Java virtual machines, which could be running either on the same or different computers. RMI allows the client code to invoke methods on an object on the server in a straightforward manner. The complexity of data-exchange is handled by the underlying transport layer which uses object serialization to communicate information over the network (see [13]). The RMI implementation of the present application is as follows: the client code accepts the input parameters from user via a user-interface and marshals them off to the server and invokes the remote GSLR solver method (running on server machine). After the computation is done, the server returns the solution arrays (eg. Mach number, pressure coefficient etc.) back to the client for further processing and graphical display.

4. Java RMI with JNI – The RMI and JNI API’s can be combined to provide a powerful, yet simple, mechanism of re-architecting legacy C/F77 codes in a distributed client-server paradigm. In addition to re-use of the native code on the server and the accompanying performance benefits of native implementation, this combination maintains portability of the client code and is well-suited to a two-tier system (see [14]) in which multiple heterogeneous clients are connected to a dedicated server. The incorporation of native C solver in the server RMI code via JNI was straightforward and was done in a fashion similar to item 2.

4 Graphical Post-Processing

In addition to investigating the performance of Java, this study also examines the effectiveness of Java graphics capability for postprocessing field equation results. While the two-dimensional nature of Java’s current graphics make the display of three-dimensional models a significant undertaking, the display of two-dimensional results is straight-forward. A certain amount of unexpected effort resulted from Java’s lack of ability to draw individual points in its canvas objects. This difficulty could have been circumvented by drawing line segments of one-pixel length, or by rendering the results to an image in memory. For easy expandability to future work involving the animated display of a time-sequence of consecutive datasets, the latter method was chosen.

Figure 1 shows the computational grid used in the case study. Data was computed at every intersection of lines in the grid. Every data value was assigned a corresponding color value, with red representing higher mach numbers and green indicating areas of less pressure. The color of any given line segment is linearly interpolated between the color values of each of its end-points, to create a pictoral representation of the Mach number in the area around the airfoil. Note that the airfoil itself does not appear in the image. If it were drawn here, it would be along the upper edge of the image, with the red area on the grid coinciding with the location of shock wave (occurring near the trailing edge of the airfoil).

A zoomed in view is shown in figure 2; includes only the portion of the grid near the trailing edge of the airfoil. Note that the portion of the grid shown in figure 2 is the region where the grid lines are the most densely spaced, to show the shockwave area in greater resolution.

Finally, figure 3 shows Java WorkShop 2.0 Beta ([15]) development environment, including the the post-processing applet shown in the Applet Viewer.

5 Benchmarking Results

Timings for the solution of equations 1–2 are summarized in Table 1. The Ultra1 170E used in this study contained a 167MHz UltraSPARC module with 0.5MB external cache ([7]) and running Solaris 2.5.1 operating system.

Two cases are presented by column (table 1), one entirely subsonic (M_{∞} = 0.74), and a supercritical case (M_{∞} = 0.94). The runs typically required about ∼ 100 iterations to converge to an accuracy of 10^{−4} in the solution. However, for uniformity of measurement and to ensure a sufficiently long run-time for accurate timing, an iteration count of eight hundred was used in the runs presented here.

The times presented in table 1 are for the iterative solver only^{1}; this portion however, accounts for more than 90% of the total run-time for a C-only implementation. It should be noted though, that exclusion of the interpreter, compiler, and initialization phases of the solution tends to accentuate the performance differences for large problems.

The first row of Table 1 shows the bytecode interpretation using javac and java from the recently released JDK1.1.1 ([10]). In the second row, results using the JIT ([8]) compiler are presented. JIT or Just In Time compiler generates code in native machine-instructions from the javac generated byte-codes at run-time. Comparing to the performance of baseline interpreted code, JIT generated code shows approximately a 4 fold increase in solver speed while retaining portability. Similar (or higher) performance improvements have been observed in other floatingpoint intensive benchmarks (see [9]).

Times for JNI implementations, compiled using differing levels of optimization, are shown in the last three rows of Table 1. Roughly a two-fold increase in speed of the /opt/SUNWspro/SC4.2/bin/cc -g over the JIT case is seen. Another two-fold increase in speed of the cc -O over the debug case is observed, with little increase in compile time. This level of optimization performs subexpression elimination and block merging amongst others.

The last row shows times an additional 2x increase in processing rate, using the flags -fast -xtarget=ultra -xarch=v8plus which enable UltraSPARC specific registers and scheduling as well as optimizations such as loop unrolling.

The benchmarking of the client-server RMI code is difficult as it depends on the characteristics of the network (such as speed, load, physical distance etc.) connecting the client and the server. Nevertheless, to estimate the overhead incurred due to the data-transfer between the client and the server, we carried out benchmarks that compared the performance when both the client and server processes are running on the same machine (referred to as local) and when they run on different machines (referred to as remote), respectively. The time taken in the method invoking the remote methods on the client machine was measured alongwith the time taken on the server machine in the method invoked by the client. The overhead of network traffic and the underlying calls made by RMI class libraries can be estimated as the difference of these two measurements.

Table 2 shows the results of these measurements for the two cases discussed above. The 112×96 grid runs are for M_{∞} = 0.74 and 140 × 112 grid runs for M_{∞} = 0.94, respectively; in all cases 800 GSLR iterations were run. Note, the server time includes time in post-processing routines also and hence is larger than those listed as interpreted (row 1) in table 1. The SS5 is based on 83 Mhz SuperSparc microprocessor, running Solaris 2.5.1, while Ultra 170E is based on 167 Mhz UltraSparc microprocessor, running Solaris 2.6 Beta release operating system version.

The timings for the truly distributed cases (i.e. client and server on different machines) were obtained during evening hours, when the network was lightly loaded. Repeated measurements were made to ensure acceptable repeatability in the results. As expected, the overhead increases with the problem sizes since the server sents back field variables (computed over the entire grid) to the client. Note, the consistency in the estimated timings between the local and remote cases for the two grids (the remote time is ∼ 2.8 times larger than the local time for both the grids).

1The time in initialization and post-processing routines has been excluded.

Overall, these results show that the overhead in the RMI calls and network transfer is reasonable (≈ 12% of the time on server for remote case) and distributed computing in Java via RMI is feasible for the present application. Further RMI benchmarks (including running the code via JIT) and comparison with socket based implementation is currently underway and results will be reported in a later paper.

6 Conclusions

A prototype code has been used to demonstrate the Java featureset as applied to a scientific application. The integration of the numerically intensive solver with a graphical interface has been demonstrated, with extension to a client-server implementation via the RMI interface.

Qualitatively, the code development process showed that the tools and environment, though basic in functionality, were quickly adopted to productive use. Implementation of distributed capability via RMI was straightforward, though the AWT lacked high-level interfaces which would speed development time. Overall, it was found that the platform was convenient to develop and deploy on, but additional support for interface design is warranted.

Performance measurements for the solver kernel showed time differences between the JIT and low optimization C compilation, both of which have the criterion of passing code quickly, are within a factor of three. However, an order of magnitude difference in speed between Java and optimized statically compiled native code has been shown for the solver procedure.

The performance discrepancy between native and JIT code will tend to decrease as dynamic compilation techniques improve, and Java front ends for native code generators become available. Other developments, such as low cost/power Java processors may also impact the price/performance ratio for scientific simulations, and certainly increase the availability of such remote computational capability.

Despite the performance degradation imposed by portability, several trends favor the use of Java in engineering environments. Firstly, the increasing integration of simulation and product development cycles favors the separation of compute cycle servers and lightweight client user front ends. Maintenance of a fewer high-performance compute sites simplifies system administration, while use of a portable language on both server and client side may simplify procurement as well, as porting concerns are mitigated.

Secondly, as the benefits of high-order computational simulation are applied to less costly products, some designers will not be able to justify the capital costs of dedicated compute server. For such manufacturers, the availability of a browser ready solution, with client-end specification of the problem may be an attractive option.

Finally, the demand for high-fidelity prediction capability has led to the development of multidisciplinary codes. Such codes typically do not incorporate the best features of, say a finite-element structural code and a fluids solver, due to the enormous interface problem. Encapsulating the logic within smaller components via object orientation may offer a means of easing the interface burden.

References

[1] Gosling, J., Joy, W. & Steele, G. Java Programming Language. Addison-Wesley, Reading, Massachusetts, (1996).

[2] Cornell, G. & Horstmann, C.S. Core Java. The SunSoft Press, Mountain Views, California, (1997).

[3] D.A. Anderson, J.C. Tannehill & R.H. Pletcher, Computational Fluid Mechanics and Heat Transfer. Hemisphere Publishing Corporation (1984).

Implementation  Case 1 (M_{∞} = 0.74, 112 × 96 grid) Case 2 (M_{∞} = 0.94, 140 × 112 grid)
Times (in sec.)  Times (in sec.)
Interpreted  618  901
SunSoft JIT compiled  155  206
JNI (C debug)  93  137
JNI (C unoptimized)  46  68
JNI (C optimized)  26  35

Table 1: Java TSD benchmarks (times are for 800 iterations of Gauss-Seidel line relaxation solver on an Ultra1 170E, Solaris 2.5.1).

Grid  Client  Server  Measured  Measured  Estimated time
time on  time on  in RMI calls and
client (sec.) server (sec.) network transfer(sec.)
112 × 96 Ultra 170E Ultra 170E  667  638  29
SS5  Ultra 170E  717  636  81
140 × 112 Ultra 170E Ultra 170E  980  940  40
SS5  Ultra 170E  1038  924  114

Table 2: RMI benchmarks for a local (client and server running on Ultra 170E) and remote configurations [client running on Sun SparcStation 5 (SS5) and server running on Ultra 170E; the two machines were on a LAN connected by 10baseT ethernet].

[4] C. Hirsch, Numerical Computation of Internal and External Flows. John Wiley and Sons, (1994).

[5] E.M. Murman & J.D. Cole, Calculation of Plane-Steady Transonic Flows. In AIAA Journal, vol. 9, (1971), p 114.

[6] 100% Pure Java Certification Tools. www.suntest.com/100percent/ (SunTest division).

[7] The Ultra1 Architecture – Technical White Paper, www.sun.com/desktop/products/Ultra1.

[8] SunSoft Java JIT Compiler, see www.sun.com/workshop/java/jit.

[9] Java JIT Compiler Performance, see www.sun.com/workshop/java/jit/performance.html.

[10] Java Development Kit – JDK1.1.1, see www.javasoft.com/products/jdk/1.1.

[11] Java Native Interface (JNI), see www.javasoft.com/products/jdk/1.1/docs/guide/jni.

[12] Wollrath, A., Waldo, J. & Riggs, R., Java Remote Methods Invocation System. Submitted to IEEE Micro. (1997).

[13] Sutherland, D., Distributing Java across your Enterprise. In Internet and Java Advisor, vol. 1, no. 10, (1996).

[14] Linden, P., V., D., Not Just Java. SunSoft Press, Mountain View, California (1997).

[15] Java Workshop Developer Product, www.sun.com/workshop/java.

./white2.ps 90 2.6 -290 -430 100 0

Figure 1: Java Applet visualization of the computational grid used for M_{∞} = 0.94 runs on a test 28 × 12 grid (every fourth point in x and every second point y direction is plotted); colors are used to represent the Mach number values at the individual grid-points. ./image1.ps 75 4.3 -290 -445 100 0

Figure 2: Expanded view of the grid in the vicinity of shock wave (the zooming feature was incorporated in the applet). The shock wave is located in the region where the grid clustering is greatest.

./image3.ps 100 8.2 -290 -690 95 0

Figure 3: A view of the Java Workshop 2.0 Beta development environment for post-processing applet.