Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multicore Java Program with Native Code

I am using a native C++ library inside a Java program. The Java program is written to make use of many-core systems, but it does not scale: the best speed is with around 6 cores, i.e., adding more cores slows it down. My tests show that the call to the native code itself causes the problem, so I want to make sure that different threads access different instances of the native library, and therefore remove any hidden (memory) dependency between the parallel tasks. In other words, instead of the static block

static {
    System.loadLibrary("theNativeLib");
}

I want multiple instances of the library to be loaded, for each thread dynamically. The main question is if that is possible at all. And then how to do it!

Notes: - I have implementations in Java 7 fork/join as well as Scala/akka. So any help in each platform is appreciated. - The parallel tasks are completely independent. In fact, each task may create a couple of new tasks and then terminates; no further dependency!

Here is the test program in fork/join style, in which processNatively is basically a bunch of native calls:

class Repeater extends RecursiveTask<Long> {
    final int n;
    final processor mol;

    public Repeater(final int m, final processor o) {
        n=m;
        mol = o;
    }
    @Override
    protected Long compute() {
        processNatively(mol);
        final List<RecursiveTask<Long>> tasks = new ArrayList<>();
        for (int i=n; i<9; i++) {
            tasks.add(new Repeater(n+1,mol));
        }

        long count = 1;
        for(final RecursiveTask<Long> task : invokeAll(tasks)) { 
            count += task.join(); 
        }
        return count;
    }
}
private final static ForkJoinPool forkJoinPool = new ForkJoinPool();

public void repeat(processor mol)
{
    final long middle = System.currentTimeMillis();     
    final long count = forkJoinPool.invoke(new Repeater(0, mol));
    System.out.println("Count is "+count);
    final long after = System.currentTimeMillis();      
    System.out.println("Time elapsed: "+(after-middle));
}

Putting it differently: If I have N threads that use a native library, what happens if each of them calls System.loadLibrary("theNativeLib"); dynamically, instead of calling it once in a static block? Will they share the library anyway? If yes, how can I fool JVM into seeing it as N different libraries loaded independently? (The value of N is not known statically)

like image 469
Mahdi Avatar asked Aug 20 '12 13:08

Mahdi


People also ask

Can Java run on multiple cores?

You can make use of multiple cores using multiple threads. But using a higher number of threads than the number of cores present in a machine can simply be a waste of resources. You can use availableProcessors() to get the number of cores. In Java 7 there is fork/join framework to make use of multiple cores.

Does Java support parallelism?

Java SE provides the fork/join framework, which enables you to more easily implement parallel computing in your applications.

How many threads can concurrently Java?

concurrent package is 16.


1 Answers

The javadoc for System.loadLibrary states that it's the same as calling Runtime.getRuntime().loadLibrary(name). The javadoc for this loadLibrary (http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#loadLibrary(java.lang.String) ) states that "If this method is called more than once with the same library name, the second and subsequent calls are ignored.", so it seems you can't load the same library more than once. In terms of fooling the JVM into thinking there are multiple instances, I can't help you there.

like image 89
mikeythemissile Avatar answered Oct 07 '22 05:10

mikeythemissile