7

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の値は静的にはわかりません)

4

2 に答える 2

2

のjavadocにSystem.loadLibraryは、を呼び出すのと同じであると記載されてい Runtime.getRuntime().loadLibrary(name)ます。このためのjavadoc loadLibraryhttp://docs.oracle.com/javase/7/docs/api/java/lang/System.html#loadLibrary(java.lang.String))には、「このメソッドが同じライブラリ名で1回実行すると、2回目以降の呼び出しは無視されます。」したがって、同じライブラリを複数回ロードすることはできないようです。JVMをだまして複数のインスタンスがあると思わせるという点では、私はそこであなたを助けることはできません。

于 2012-08-20T14:11:43.570 に答える
0

共有リソースにボトルネックがないことを確認する必要があります。たとえば、ハイパースレッドコアが6つある場合、12スレッドが最適であるか、6スレッドが最適であることがわかります(各スレッドには専用のコアがあります)。

浮動小数点ルーチンが重い場合、ハイパースレッディングは高速ではなく低速になる可能性があります。

すべてのキャッシュを使用している場合、さらに使用しようとすると、システムの速度が低下する可能性があります。CPUの制限をメインメモリの帯域幅に使用している場合、より多くの帯域幅を使用しようとすると、マシンの速度が低下する可能性があります。

では、どうすればさまざまなインスタンスを参照できますか?ロードされたクラスは同じ名前とパッケージを持つということですよね?同じ名前とパッケージのクラスを含む2つのダイナミックライブラリをロードすると、一般的に何が起こりますか?

インスタンスは1つだけで、DLLを複数回ロードすることはできません。スレッドごとに異なるデータセットを構築する場合は、これをライブラリの外部で行い、これをライブラリに渡して、各スレッドが異なるデータを処理できるようにする必要があります。

于 2012-08-20T19:36:24.503 に答える