The latter can be found here.If your platform does not already have the necessary Java version installed you can download it from one of several locations:
Older Tonic distributions, including those which work against Jini 1.1 and earlier, can be found here. Note that while the Tonic classes have been compiled and tested several times under Windows98, the script utilities described on this site primarily support Unix/Linux. The issue of running Tonic clients on Windows and Macintosh platforms is nominally discussed below.which tells configure:
The configure script will emit various messages (the locations of
your Jini/JavaSpaces and JDK distributions, the number of processors on
your host, your internet domain, etc) and then generate configuration
scripts, Makefiles, and other support files specifically customized
for your site. Check the results to ensure things are in reasonable order.
You generally need to run configure only once per version
you download, but you may run it as many times as you wish. Use
unix% ./configure --help
to list the many other customization options that are available. Note that
while technically all configure switches are optional (e.g. TSpaces is not
required to use Tonic), the --with-jinidir should probably always be
specified, since if Jini cannot be found automatically (perhaps because it's
been installed in some non-standard location) you will not be able to use
Tonic at all.
To fully clean your Tonic distribution, including removing the files generated
by configure, do
unix% [g]make distclean
Starting HTTP server to furnish JINI/JavaSpaces class files... ... process id is XXXXX Starting rmid... ... process id is XXXXX Starting Jini lookup server ... ... process id is XXXXX Starting JavaSpaces ... ... process id is XXXXXTo conserve memory Tonic launches these background processes with an initial Java heap size of 3Mb. If this conflicts with your JDK (you'll know because either startSpace or the Tonic runtime will fail), you can increase the heapsize by either using a custom Tonic resource file or by re-running configure with the heapsize option.
found JavaSpaces = com.sun.jini.outrigger.SpaceProxy@1
1.339 sec to contact space
Size of NullIO$NullEntry as a serialized class is ~37 bytes
Size of NullIO$NullEntry as an instantiated+serialized object is ~37 bytes
Size of NullIO$NullEntry wrapped in a Jini/JavaSpaces Entry is ~333 bytes
# Testing with zero-field NullEntry:
# nobj write w/sec sec/w Kbytes/sec take t/sec sec/t
# ---- ----- ----- ----- ---------- ---- ----- -----
100 0.971 102.9866 0.0097 33.4908 1.005 99.5025 0.01
100 0.868 115.2074 0.0087 37.4649 1.342 74.5156 0.0134
100 0.881 113.5074 0.0088 36.9121 0.954 104.8218 0.0095
100 0.925 108.1081 0.0093 35.1563 0.813 123.0012 0.0081
100 0.77 129.8701 0.0077 42.2332 0.789 126.7427 0.0079
Mean for 100 objects:
write: 0.883 113.2503 0.0088 36.8285
take : 0.9806 101.9784 0.0098
Number of processors/tasks = 1 Number of iterations = 100000000 N (problem size) = 10 Error tolerance = 1.0E-8 Task: Pi Size of Pi as a serialized class is ~179 bytes Size of Pi as an instantiated+serialized object is ~366 bytes Size of Pi wrapped in a Jini/JavaSpaces Entry is ~1045 bytes 0.0 sec to generate task(s) (sequential) Computing Pi task # 0 20.709 sec Total : to strictly perform the computation PI is approximately 3.1415926735904267Now let's try the same computation on the same machine, this time using two workers. One way to do this is to launch the workers in two separate windows (if you create these windows as new login processes recall that you would need to run tonic.[c]csh in each, as given above):
Number of processors/tasks = 2 Number of iterations = 100000000 N (problem size) = 10 Error tolerance = 1.0E-8 Task: Pi Size of Pi as a serialized class is ~179 bytes Size of Pi as an instantiated+serialized object is ~366 bytes Size of Pi wrapped in a Jini/JavaSpaces Entry is ~1045 bytes found JavaSpaces = com.sun.jini.outrigger.SpaceProxy@1 1.147 sec Total : time to contact the space reducer: starting run ... 0.27 sec to distribute the tasks ComputeMaster: got result for task #0 ... ComputeMaster: got result for task #1 ... 12.815 sec to collect the tasks 13.105 sec Total : to strictly perform the computation PI is approximately 3.141592673590022Note that in this example the master, workers, and space were all run on the same host, but because it's a multiprocessor we still see a marked performance improvement. Try launching more workers (and changing -P) to see if the runtime can be reduced yet further.
Usage: java ComputeMaster task_name [options]
Options:
-e ## = error tolerance for iterative solvers
(default = 1e-8)
-P ## = number of 'processors', subdivides computation into ## tasks
(default = 1, sequential execution)
-niter ## = number of iterations/subintervals
(where applicable; default value = 1e8)
-n ## = problem size (eg, NxN grid for Jacobi,etc)
These case-sensitive computation names may be used:
Pi PI computation (default task,uses niter=1e8)
Jacobi naive Jacobi iterative solver
Dynamic dynamic compilation
NeutronShield neutron shielding parametric experiment
Sieve generate all prime numbers <= N, using a
parallel Sieve of Erastosthenes
Heat Monte Carlo simulation of source heating
in an isotropic scattering medium
Scattering = 20.000/cm Absorption = 2.000/cm Photons = 100000, Shell thickness (microns) = 50.000 Radius Heat [microns] [W/cm^3] Total run time 10.986038Now we'll run the same algorithm on the same machine, this time with Java 1.3:
Number of processors/tasks = 1 N (problem size) = 100000 Task: Heat Size of Heat as a serialized class is ~202 bytes Size of Heat as an instantiated+serialized object is ~382 bytes Size of Heat wrapped in a Jini/JavaSpaces Entry is ~832 bytes Scattering = 20.0/cm Absorption = 2.0/cm Photons = 100000 Shell thickness (microns) = 50.0n Radius Heat [microns] [W/cm^3] 16.1 sec Total : to simulate 100000 photonsNotice how the sequential Java version is 47% slower than C. At first glance this may seem terrible, but relative to JDK1.2.2, which took 51 seconds (464% slower than C) to execute the same code, it's actually quite good. Let's see if we can make it faster by dividing the problem amongst 2 JavaSpaces Workers (one on the same machine, another on a machine of equal speed). Here, again, the algorithm is coded in Java:
Number of processors/tasks = 2 N (problem size) = 50000 Task: Heat ComputeMaster: got result for task #1 ... ComputeMaster: got result for task #0 ... 9.142 sec Total : to strictly perform the computationThis is much faster than the sequential Java, but notice that the 2 JavaSpaces Worker processes are barely faster than the single C process. Let's try 3 Workers:
Number of processors/tasks = 3 N (problem size) = 33333 Task: Heat ComputeMaster: got result for task #2 ... ComputeMaster: got result for task #0 ... ComputeMaster: got result for task #1 ... 6.529 sec Total : to strictly perform the computationWe now see an appreciable speedup over the C code, but are working hard to get it. In the ideal case using 3 processors would yield 3x speedup over 1 processor, but in our case we are seeing 10.98/6.529 = 1.68 speedup, or an efficiency of 1.68/3 = 56%. Now let's turn to the Tonic dynamic compilation technique to see if we increase efficiency and squeeze out more performance. In this approach the Dynamic tuples do not contain Java code, but rather C source code objects, which when extracted by a Worker will be compiled to a native binary library, loaded, and invoked through JNI.
Number of processors/tasks = 2 N (problem size) = 50000 Task: Dynamic Size of Dynamic as a serialized class is ~218 bytes Size of Dynamic as an instantiated+serialized object is ~3514 bytes Size of Dynamic wrapped in a Jini/JavaSpaces Entry is ~4001 bytes ComputeMaster: got result for task #1 ... ComputeMaster: got result for task #0 ... 5.619 sec Total : to strictly perform the computationThis is considerably better, as with two processors we have a speedup of 10.98/5.62 = 1.95, or 97.5% efficiency. Thus we see that for short, compute-intensive codes the overhead of dynamically compiling to native binaries is small compared to the total algorithm computation time.