8

Java 数値アルゴリズムのパフォーマンスについて興味があります。たとえば、最新の JIT マシンを使用して、手動で調整された SSE C++/アセンブラーまたは Fortran の対応するものと比較して、マトリックス マトリックスの倍精度乗算などです。

私は Web を見てきましたが、ほとんどの結果はほぼ 10 年前のものであり、それ以来 Java がかなり進歩したことを理解しています。

数値集約型のアプリケーションに Java を使用した経験がある場合は、その経験を共有していただけますか。また、ループが比較的短く、メモリアクセスがあまり均一ではないが、L1 キャッシュの制限内にあるカーネルで、Java はどの程度うまく機能するでしょうか? そのようなカーネルが連続して複数回実行される場合、JVM は実行時にそれを最適化できますか?

ありがとう

4

9 に答える 9

2

私は Java で適度に大きく、パフォーマンスに敏感な数値コードをいくつか書きました (通常は double の大きな配列をクランチします)。

Java は、数値計算を高速に行うには「十分」であることがわかりました。特に、とにかく通常は CPU バウンドではないことを考えると、メモリの待ち時間とキャッシュの認識が、おそらく大規模なデータセットの最大の問題になるでしょう。

ただし、特定のベクトル化された命令などを利用する手動で最適化された C/C++ コードや、高度にカスタマイズされたメモリ レイアウトを使用することで、Java を打ち負かすことができます。したがって、非常に高速なコードを作成するには、コア アルゴリズムを C/C++ で記述し、JNI を使用して Java から呼び出すことを検討してください。

個人的には、ネイティブ コードの依存関係を作成することは、通常、価値があるよりも面倒であることがわかっているため、純粋な Java アプローチに固執する傾向があります。

于 2011-03-14T17:36:37.660 に答える
1

C++ は間違いなく高速になります。主要な各 CPU のアセンブリ コードを含む、手動で最適化されたライブラリを使用することもできます。あなたはそれより良くなることはできません。

その後、必要に応じて、JNI を使用して Java から呼び出すことができます。

Java は、このような高パフォーマンスの算術計算には向いていません。これらに依存している場合は、適切な低レベル言語を選択して実装することをお勧めします。または、パフォーマンス固有の部分を低水準言語で記述し、JNI またはその他の IPC メソッドを使用して Java フロントエンドに接続することもできます。

于 2009-11-09T15:28:21.027 に答える
1

これは、Java と C++ のプログラミング言語の銃撃戦ページへのリンクです。このページでは、いくつかの計算集約型アルゴリズムでの Java の速度を比較できます。また、最高パフォーマンスの Java コードがどのようなものかを示します。ほとんどの場合、これらのいくつかの特定のベンチマークでは、Java の実行に時間がかかりました (ただし、2 ~ 3 倍以内)。

于 2009-11-09T01:15:26.880 に答える
1

これは .NET 側から来ていますが、Java にも当てはまると 90% 確信しています。JIT は可能な限り SSE 命令を使用しますが、現在のところ、行列の乗算などを処理する際にコードを自動ベクトル化することはありません。ここでは、コンパイラ組み込み関数/インライン アセンブリを使用して手動でベクトル化された C++ の方が確実に高速になります。

于 2009-11-09T01:15:27.220 に答える
1

Java の最も弱い点の 1 つは、(ネイティブの) 行列演算です。これは、Java マトリックスの性質によるものです。

  • 行列を長方形であると宣言することはできません。各行は異なる数の列を持つことができます。

  • 行列は、技術的には「double (または ints、...) の行列」ではなく、... の配列の配列です。大きな違いは、配列は Java オブジェクトであるため、同じ配列オブジェクトを複数の行に割り当てることができることです。

これら 2 つのプロパティにより、多くの標準的な行列の最適化がコンパイラで不可能になります。

単一の長い配列で行列をエミュレートする Java ライブラリを使用すると、パフォーマンスが向上する場合があります。ただし、すべてのアクセスに対してメソッド呼び出しのオーバーヘッドがあります。

于 2009-11-09T02:57:41.527 に答える
0

高速フーリエ変換、ヤコビ逐次的緩和、モンテカルロ積分、疎行列多重、密 LU 行列因数分解などの種類の計算に興味がありますか?

これらは、マシン上でアプレットとして起動できるSciMark 2.0 複合ベンチマークを構成します。

プログラムのANSI C バージョンと、 SciMark for C++の最適化と再コンパイルに関する Intel ドキュメント (pdf)もあります。


同様に、Java Grande Forum Benchmark Suite比較 C プログラムを使用できます。

于 2009-11-09T17:52:37.577 に答える
0

これは、C++ コードで何をしているかに大きく依存する可能性があります。

たとえば、GPU を使用していますか。編集jogl を忘れていたので、Java はここで競合できます。

STM または共有メモリを使用して並列化されている場合、Java は競合できません。並列行列乗算の分析に関するリンク: http://www.cs.utexas.edu/users/plapack/papers/ipps98/ipps98.html

ガベージ コレクターが不要になるように、メモリ内で計算を行うのに十分なメモリがありますか? また、最適なパフォーマンスが得られるようにガベージ コレクターを微調整しましたか? そうすれば、おそらく Java は競争力を持つことができます。

マルチコアを使用していますか? また、C++ はこのアーキテクチャを利用するように最適化されていますか? そうなると、Java は競争できなくなります。

一緒に接続された複数のコンピューターを使用している場合、Java は競合できません。

これらの組み合わせを使用していますか?それは特定の実装に依存します。

Java は手作業でチューニングされた C++ プログラムと競合するようには設計されていませんが、チューニングにかかる​​時間は、重要な部分で十分な計算を行っていますか? Java はある程度の速度を実現できますが、手動で調整するよりも少ない作業で済みますが、C++ コードを実行するだけの場合よりも大幅に改善されるわけではありません。

Haskell や Erlang よりも、たとえば C++ よりも改善されているかどうかを確認したい場合があります。これらの言語は、この種の作業用に設計されているためです。

于 2009-11-09T01:35:27.090 に答える
0

正確に何をしているかによってパフォーマンスが多少異なるため、最善の策は自分でテストすることです. Java のパフォーマンスは C++ または Fortran のパフォーマンスと同じになるという Shane C. Mason の回答を信じるのは難しいと思います。

C++ を使用して記述した計算流体力学コードと、本質的に Fortran に変換された同じコードがあります。理由はまだよくわかりませんが、Fortran 版は C++ 版の約 2 倍高速です。境界チェックやガベージ コレクションなどの機能を使用すると、Java は両方よりも遅くなると思いますが、テストするまではわかりません。

于 2009-11-09T01:14:49.613 に答える
-4

Java は、ジャスト イン タイム (JIT) コンパイラを使用してバイトコードをネイティブ マシン言語に変換します。そのため、最初にコード ブロックを実行するときは遅くなりますが、セグメントが「ウォームアップ」されると、パフォーマンスは同等になります。要するに、数値パフォーマンスはかなり良いです。

于 2009-11-09T01:05:12.003 に答える