特定のメソッドで大きな_c/asm
_データにGPU(OpenCL)を利用するネイティブ_encrypt/decrypt
_アプリケーションがあり、問題なく完璧に動作します。プロジェクトの一部(Webおよびディストリビューション)はJEE
によって開発されており、ネイティブアプリケーション/ライブラリを呼び出すだけです。
Process
クラスを使用して、分離外部プロセスとして呼び出すことを試みました。問題は、アプリケーション(イベント、ハンドラー、スレッドなど)を制御できないことです。また、CコードをJavaコードに切り替えようとしましたが、パフォーマンスは低下しました。ネイティブコードをプロセスとして実行する以外は、JNAとJNIについて考えていますが、いくつか質問があります。
質問:
ByteBuffer#allocateDirect()
)]でデータを交換することは可能ですか?Redhat Linux6 x64に2つのAMD W7000クラスターデバイスがあります。
JNAはJNIよりもはるかに低速ですが、はるかに簡単です。パフォーマンスに問題がない場合は、JNAを使用します。
ダイレクトバッファを使用すると、最も重要な操作でJNIまたはJNAを使用しないため、高速になるという利点があります。単一のマシンコード命令に変換されることを意味する場合、組み込み関数を使用します。
JavaコードがCよりも大幅に遅い場合、コードが十分に最適化されていない可能性があります。一般に、GPUがすべての作業を実行する必要があるため、Javaが少し遅い場合、これは大きな違いにはなりません。
例えばGPUで99%の時間を費やし、Javaの2倍の時間がかかると、合計は99 + 2%または1%遅くなります。
単純なdllを開発し、何もしない空の関数を配置しました。次に、JNAおよびJNIを使用してdllからその関数を呼び出したため、呼び出しのコストを計算しようとしました。何度も呼び出した後のパフォーマンスを見ると、JNIはJNAより30〜40倍高速でした。
JNAの公式FAQ から:
JNAのパフォーマンスはカスタムJNIと比較してどうですか?
JNAダイレクトマッピングは、カスタムJNIに近いパフォーマンスを提供できます。インターフェイスマッピングのほぼすべてのタイプマッピング機能を使用できますが、自動タイプ変換には多少のオーバーヘッドが発生する可能性があります。
JNAインターフェースマッピングを使用した単一のネイティブコールの呼び出しオーバーヘッドは、同等のカスタムJNIよりも1桁(〜10倍)長い場合があります(アプリケーションのコンテキストで実際に実行されるかどうかは別の質問です)。生の用語では、呼び出しのオーバーヘッドは数十マイクロ秒ではなく、数百マイクロ秒のオーダーです。これは総通話時間ではなく、通話のオーバーヘッドです。この大きさは、動的に維持される型情報を使用するシステムと型情報が静的にコンパイルされるシステムの違いの典型です。 JNIは、メソッド呼び出しで型情報をハードコーディングします。JNAインターフェイスマッピングは、実行時に型情報を動的に決定します。
JNAダイレクトマッピングへの移行は約1桁のスピードアップ、そこからカスタムJNIへの移行は2〜3倍になると思われるかもしれません。実際の違いは、使用法と関数のシグネチャによって異なります。最適化プロセスと同様に、最初に速度を上げる必要がある場所を判断し、ターゲットを絞った最適化を実行して、どれだけの違いがあるかを確認します。 Javaですべてをプログラミングすることの容易さは、通常、カスタムJNIを使用する場合のわずかなパフォーマンス向上を上回ります。
重い数値の処理はC/GPUで行われ、すべてのJava <-> Cインターフェースはデータの入出力をシャッフルするだけです。これがボトルネックであれば驚かされるでしょう。
いずれにせよ、仕事をする最も単純で明確なコードを書いてください。パフォーマンスが十分でないことが判明した場合は、measureボトルネックがどこにあるかを確認し、パフォーマンスが正常になるまで1つずつ対処します。非常に特別な状況を除いて、プログラマーの時間はコンピューターの時間よりもはるかに貴重です。