Javaプログラム内でネイティブC++ライブラリを使用しています。Javaプログラムは、メニーコアシステムを利用するように作成されていますが、拡張性はありません。最高速度は約6コアです。つまり、コアを追加すると速度が低下します。私のテストでは、ネイティブコード自体を呼び出すと問題が発生することが示されているため、異なるスレッドがネイティブライブラリの異なるインスタンスにアクセスすることを確認し、並列タスク間の隠れた(メモリ)依存関係を削除します。言い換えれば、静的ブロックの代わりに
static {
System.loadLibrary("theNativeLib");
}
スレッドごとに、ライブラリの複数のインスタンスを動的にロードする必要があります。主な問題は、それが可能かどうかです。そして、それを行う方法!
注:-Java7のfork/joinとScala/akkaに実装があります。したがって、各プラットフォームでのヘルプは大歓迎です。-並列タスクは完全に独立しています。実際、各タスクはいくつかの新しいタスクを作成してから終了する場合があります。それ以上の依存関係はありません!
これがフォーク/ジョインスタイルのテストプログラムで、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の値は静的にはわかりません)