我在 Java 程序中使用本机 C++ 库。Java 程序是为使用多核系统而编写的,但它无法扩展:最好的速度是使用大约 6 个内核,即添加更多内核会减慢速度。我的测试表明对本机代码的调用本身会导致问题,因此我想确保不同的线程访问本机库的不同实例,从而消除并行任务之间的任何隐藏(内存)依赖关系。换句话说,而不是静态块
static {
System.loadLibrary("theNativeLib");
}
我希望为每个线程动态加载库的多个实例。主要问题是这是否可能。然后怎么做!
注意: - 我在 Java 7 fork/join 以及 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的值是静态未知的)