0

物理モデリングの計算を高速化するために JNI を使用するプロジェクトの準備をしています。ネイティブ部分は、それぞれが 10M を超える要素を持つ配列のグループに対して計算を行います。

質問: パフォーマンスに適したオプションは次のうちどれですか。

1) Java で 8 つのスレッドを使用し、それぞれがネイティブ呼び出し (jni-->c++) を介して配列の 1/8 部分で動作します。不要な配列のコピーを防ぐために、配列全体を小さな配列にトリミングする必要がありますか?

2) 8 スレッド (pthreads?) のネイティブを呼び出す Java でシングル スレッドを使用して、スレッドで使用するために必要な部分のみを選択するためにポインター演算を使用できますか?

配列の 1 つのコピー (またはオリジナル) で作業する必要があります。C++ スレッドは配列全体をコピーしますか? Javaスレッドはどうですか?どれがコピーではないか、それを使用します。

注:GetPrimitiveArrayCritical()JNIインターフェースの配列コピー(オリジナルでの作業)を防ぐために使用しています。計算には、JNI のオーバーヘッドを無視できるほどの時間がかかります。

GetPrimitiveArrayCritical()ネイティブ関数がそれを解放するまでGCが動作を停止するようにJava配列を固定しますが、これは他のJavaスレッドのアクセシビリティに影響しますか?

実際にはすべてがextern "C"重要な場合です

OS: 64 ビット windows7 CPU: fx8150 jvm: 64 ビット GCC: 64 ビット

ありがとう。

4

1 に答える 1

2

設計の観点からは、JNI コードでスレッドを管理する必要がないことを意味するため、アプローチ #1 をお勧めします。これは「単一責任の原則」に従います。アルゴリズムが変更された場合にのみ、ネイティブ コードを変更する必要があります。また、Java が提供する機能 (スレッドプールとフューチャー) は、直接スレッドよりも使いやすいと思います。

ただし、これを行う場合は、複数のスレッドからの配列の固定および固定解除に関する警告に特に注意を払う必要があります。

IMO のより良いアプローチは、 direct を割り当て、GetDirectBufferAddressByteBufferを使用して JNI からアクセスすることです。これにより、Java 側のスレッドプールを使用して作業を管理できるようになり、バッファ コピーに関するネイティブ側の懸念が解消されます。

于 2013-07-16T14:52:16.673 に答える