Я использую собственную библиотеку C++ внутри программы Java. Программа Java написана для использования многоядерных систем, но она не масштабируется: наилучшая скорость достигается при наличии примерно 6 ядер, т. е. добавление большего количества ядер замедляет ее. Мои тесты показывают, что вызов самого нативного кода вызывает проблему, поэтому я хочу убедиться, что разные потоки обращаются к разным экземплярам нативной библиотеки, и, следовательно, удалить любую скрытую (память) зависимость между параллельными задачами. Другими словами, вместо статического блока
static {
System.loadLibrary("theNativeLib");
}
Я хочу, чтобы несколько экземпляров библиотеки загружались динамически для каждого потока. Главный вопрос заключается в том, возможно ли это вообще. А потом как это сделать!
Примечания: - У меня есть реализации fork/join Java 7, а также Scala/akka. Поэтому любая помощь на каждой платформе приветствуется. - Параллельные задачи полностью независимы. На самом деле каждая задача может создать пару новых задач, а затем завершиться; больше никакой зависимости!
Вот тестовая программа в стиле fork/join, в которой processNatively представляет собой набор нативных вызовов:
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));
}
Иными словами: если у меня есть N потоков, использующих собственную библиотеку, что произойдет, если каждый из них вызовет System.loadLibrary("theNativeLib"); динамически, вместо того, чтобы вызывать его один раз в статическом блоке? Они в любом случае будут делить библиотеку? Если да, то как я могу обмануть JVM, чтобы он увидел, что N разных библиотек загружаются независимо? (значение N не известно статически)