1

Android プロジェクトに取り組んでいますが、操作がパフォーマンスのボトルネックになることがわかりました。この操作は大きな配列 A に対して機能し、結果を別の配列 B に格納します。

この操作は並列化できることがわかりました。配列 A は N 個の小さなセグメントに分割できます。この操作は、各セグメントに対して個別に実行でき、結果を B の対応するセグメントに格納できます。

この操作は、GetPrimitiveArrayCritical/ReleasePrimitiveArrayCritical ペアを使用してネイティブ コードで記述され、配列 A と B にアクセスします。

私の質問は、マルチスレッドを使用している場合、 GetPrimitiveArrayCritical(pEnv, A, 0) が異なるスレッドから複数回呼び出されることです。GetPrimitiveArrayCritical はブロックしますか? つまり、1 つのスレッドがこの呼び出しを行った場合、最初のスレッドが ReleasePrimitiveArrayCritical() を呼び出す前に、2 番目のスレッドが同じ呼び出しを行うことができますか?

助けてください。

4

1 に答える 1

1

GetPrimitiveArrayCritical()はい、 2 つの同時スレッドから呼び出すことができます。関数はブロックされず、2 つのスレッドは基になる配列へのアクセスをネイティブ コードに許可します。しかし一方で、関数はこのアクセスを同期するために何もしません。つまり、スレッド 1 がインデックス 100 の値を変更し、スレッド 2 もインデックス 100 の値を変更した場合、どちらが最後に選択されるかわかりません。 .

配列に書き込まない場合、正しく提供されることが保証されます。フラグを付けることReleasePrimitiveArrayCriticalを忘れないでください。JNI_ABORT

配列に書き込みたい場合は、GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)isCopyによって設定された出力パラメータを確認してください。結果が 0 の場合、マルチスレッド アプローチを安全に進めることができます。

結果が 0 でない場合ReleasePrimitiveArrayCritical()、Java 配列のすべての要素が上書きされます。Java や C の別のスレッドで一部の要素が変更された場合でも同様です。プログラムがこの状況を検出した場合、配列を解放し ( を使用JNI_ABORT)、他のスレッドが完了するまで待機する必要があります。Android では、配列がコピーされているのを見たことがありません。配列は常にその場でロックされています。しかし、現在のシステムでも将来のバージョンでも、これが起こらないとは誰も保証しません。

そのため、パラメータをチェックする必要がisCopyあります。

于 2013-06-01T18:56:53.543 に答える