JSim Multiprocessing Development

This page is for the current JSim version 2.0 and higher. Click here for the earlier JSim 1.6 version.

This page is a working document for JSim internals developers working on JSim multi-processing (MP) support:


The first stage of JSim MP support will use Java threads. The user will request some number of separate run threads (probably as a command-line switch). On a machine with multiple processors, the JVM will balance the threads between available processors, increasing performance. On single processor machines, multiple threads will compete for time slots, so performance will actually be somewhat reduced, but will allow for testing during development.

Native Library Upgrades

The native code for ODE, PDE and optimizer methods will need to be upgraded to support MP. The native code may be found in $JSIMSRC/JSim/nonJava. Each method has original code in C or Fortran (e.g. radau.f) and a JNI wrapper (e.g. jradau.c). I've already modified all the JNI wrappers to support MP. There are separate data structures allocated for each thread (e.g. jsodethread.h and .c) indexed by integer threadInx. This threadInx must be passed to and returned by the native solver code.

Upgrades to each method should be as follows:

  1. threadInx becomes the 1st argument for each top-level solver function call that results in an external callback (e.g. fcn() in ODE solvers). threadInx also becomes the 1st argument in the callback. This will allow the JNI wrapper to redirect simultaneous callbacks to the correct Java code. threadInx need not be (and therefore, should not be) passed to functions that do not perform external callbacks.
  2. All solver code should be made reentrant, if at all possible. This should be straight-forward for most solvers that do everything from a single entry point (i.e. a single solver call from within the JNI wrapper). CVode may be a special case (see below).
  3. Test programs should be written in C or Fortran (as appropriate) that tests reentrancy by calling the solver recursively to 2 levels. For example, an optimizer that calls a second optimizer within its fcn() call. While not exhaustive, such tests are easy to debug, and catch many common errors.
  4. Once the above is completed, send me a copy for review. Once I have acceptable versions of code and test programs for all the solvers, I'll roll them into the JSim code base, along with appropriate changes to the JNI wrappers.

Reentrancy Guidelines for C modules

Wikipedia.org is a good source for recent computer info. See entries there reentrant, thread-safe, etc. Checking with the original code authors is probably a good idea.

Use no static variables or variables declared outside of functions unless they are constant for all threads. All called functions must be reentrant.

Send me other guidelines you think should be here.

Reentrancy guidelines for Fortran modules

Ditto comments above regarding Wikipedia.

  • everything appearing in a SAVE statement;
  • variables in COMMON blocks;
  • arrays that use more than 32kb storage.

However, arrays that are dimensioned by a dummy or COMMON variable or assumed-size arrays are put in the stack. g77 does not complain about recursive calling.

Send me other guidelines you think should be here.


MP Performance on 4 Tested Platforms:

        Multi-run Benchmark Results  (larger number indicates better performance)
        #processors     altix1  bigbox  baggins gollum
        1               100     100     100     100
        2               199     158     194     188
        4               345     235
        8               479
        16              556

        Single Run Benchmark Results (larger number indicates better performance)       
        #processors     altix1  bigbox  baggins gollum
        1               100     100     100     100
        2               197     182     184     186
        4               376     257
        8               537
        16              651


Notes for above:

  • Multi-run benchmark was a 16-run "loops" analysis using VS001 model using release 1.6.66.
  • Single run benchmark was a 32 parallel path ODE model using a prototype version of JSim 1.6.68. The model's java code was manually edited in a manner consistent with proposed changes to the JSim MML compiler.
  • Revised altix performance figures available 6 Dec 2006.
  • Performance figures are percentages based on 100% for a single processor usage on the system in question. Single processor performance on the tested systems varied by up to a factor of 3 due to hardware and OS differences.
  • "altix1" is a 128 processor SGI Altix system running JSim for Linux IA64, however our altix1 account is restricted to a maximum 16 processors for a single job. "bigbox" is a 4 processor Intel system running JSim for Linux AMD64. "baggins" is an Intel-based Mac Mini. "gollum" is a G5-based Power Mac.

Comments or Questions?

Give feedback

Model development and archiving support at https://www.imagwiki.nibib.nih.gov/physiome provided by the following grants: NIH U01HL122199 Analyzing the Cardiac Power Grid, 09/15/2015 - 05/31/2020, NIH/NIBIB BE08407 Software Integration, JSim and SBW 6/1/09-5/31/13; NIH/NHLBI T15 HL88516-01 Modeling for Heart, Lung and Blood: From Cell to Organ, 4/1/07-3/31/11; NSF BES-0506477 Adaptive Multi-Scale Model Simulation, 8/15/05-7/31/08; NIH/NHLBI R01 HL073598 Core 3: 3D Imaging and Computer Modeling of the Respiratory Tract, 9/1/04-8/31/09; as well as prior support from NIH/NCRR P41 RR01243 Simulation Resource in Circulatory Mass Transport and Exchange, 12/1/1980-11/30/01 and NIH/NIBIB R01 EB001973 JSim: A Simulation Analysis Platform, 3/1/02-2/28/07.