Javaによる数値計算 高速化

このQ&Aのポイント
  • Javaで大きな2次元配列を使用した数値計算を実施しています。
  • FortranからJavaに移植した結果、計算速度に困っています。
  • Javaで最適化あるいは高速化する方法はありますか?
回答を見る
  • ベストアンサー

Javaによる数値計算 高速化

大きな2次元配列を使った数値計算を実施しています。 これまではFortranをメインで使用していましたが、モデルへの機能追加などが容易なことから オブジェクト指向言語に取り組み、ようやくJavaに移植が完了しました。 事前に調べた所では、Fortran、C++、Javaいずれも速度に大きな差は無いとありました。 (そもそもこれは本当でしょうか?) 1~2割程度遅いのなら許容出来るつもりでしたが、いざ実行してみると、 Fortranで3ステップ進む時にJavaでようやく1ステップ進むといった感じで、少々困っております。 ⇒ そんなことあり得ないということであれば、自分のプログラムのバグを疑いますが。ただ、計算結果は概ね良好のようです。 それで、気になったのが、Fortranでは、コンパイル時に最適化してくれるのですが、 今調べたところJavaにはそれがないようです。 言われてみると、Fortranで最適化オプションを実施しなかった時にはこのくらいの遅さだったように思えます。 それで、前置きが長くなりましたが、Javaで最適化あるいは高速化する方法は無いのでしょうか? プログラミング自体が専門ではないので、できれば人間に分かりやすいコーディングのまま使いたいのですが。 初心者が陥りがちなところで、これを直せば、だいぶ速くなるというような一般的な注意事項などありましたら教えていただきたく存じます。

  • Java
  • 回答数3
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.3

補足します。 先ず、ゲッタ/セッタを使う方法とpublicの 相違ですが、変数の参照を例にすると、 ゲッタの場合はCALL→MOV→RET→MOVと いう命令になります。CALLやRETは次の 命令の集合です。ADDまたはSUB→MOV →JMP つまり、ゲッタでは8ステップの行動になり ます。一方publicのメンバを扱うと、MOVが 1回でこと足ります。どちらが有利かは一目で 分かると思います。 メンバを扱う時はクラスのアドレスをベース レジスタにロードしてから、ベース+オフセットと いう方法でアクセスします。レジスタの個数は 限られているので、メンバのまたメンバという ネストを深くすると、ベースへのロードが何度も 繰り返されてしまいます。よく使うオブジェクトを 固定すれば、ベースの入れ替え回数が減って その分だけ有利になります。 計算を一気にやるのは中間結果をレジスタに 置くためです。レジスタはCPU資源なので、 メモリよりずっと処理速度が速くなっています。 中間結果を変数に入れていると、レジスタから メモリ(変数)へのMOVが発生しますから速度は 劣化します。 インスタンスの生成/消滅はメモリ資源の管理に 影響しますから、ものすごく時間がかかります。 マルチスレッド下ではメモリ資源の干渉が起きない ように制御しますから、以外に面倒な処理です。 ランタイムは時々、空きメモリを詰める操作を 行います。これをガベジコレクション(GC)と言います。 これにあたるとガクっと処理時間が遅くなります。 Stringなどの処理も頻発すると、GCが発生します。 StringとかIntegerはオブジェクトであり、安直に 使用すると、そのつもりが無くてもインスタンスの 生成/消滅を発生させます。 いずれも「分かり易さ」からはかけ離れた方向に なりますが、コンピュータ側に立って考えると、 「人間寄り」は迷惑な話なんです。

その他の回答 (2)

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.2

1.計算に使うデータは可能な限り整数を使う。 2.メンバをゲッタ、セッタではなく、publicにして  参照する。 3.メンバ参照時、ネストが深い場合は別変数を  使う。  A.B.C.D = A.B.C.X + A.B.C.Y; →Q = A.B.C;  Q.D = Q.X + Q.Y; 4.静的(static)変数の使用は極力避ける。 5.計算はなるべく一気に行う。  a = b + c;  x = a * d; →x = ( b + c ) * d; 6.インスタンスの生成/消滅は極力回数を減らす。 上記を実施しても速くなるかどうかは分かりません。 Javaはネイティブコードではないので、C等に比べ 速度が遅いのは止むを得ないところです。 ただ、CPUの性能向上により、通常の処理では ストレスが少なくなりました。 私は機械語を長くやってきているので、2や3に 反するコーディングを見ると神経に障りますが、 ゲッタ/セッタはJavaではフツーなので目を瞑る ことにしています。

monomei
質問者

補足

ご回答ありがとうございました。 なるほど。参考になります。 教科書では、なるべく変数はprivateにして、アクセス関数でアクセスするように書かれていますが、 プログラムの安全性と速度はトレードオフになっているということでしょうか。 また、static変数は使わないほうが良いのですか?

  • ki073
  • ベストアンサー率77% (491/634)
回答No.1

私自身はJavaを使っていないので、一般的な話として書きます。 質問欄に書かれているようにFortranやCの場合は行列計算などを最適化してくれます。 コンパイラの性能によるのですが、プログラムに書いた通りではなく、最適化によりベクトル化や並列化が可能ですので、さらに1桁から2桁程度速度があがります。 もしJavaとFortranの最適化されていないものが同程度の速度がでるのなら、Javaがかなり優秀なのだと思いますが、どうなのでしょうか?この手の言語はベクトル化や並列化は基本的には行われませんので、どうしても不利になりますし、仮想マシンを使いますのでそのオーバーヘッドがどうしても大きくなります。 解決方法ですが、行列やベクトル(上記のベクトル化とは違い数学ででてくるベクトル)のライブラリを使うのが良いように思います。 例えば http://www.oishi.info.waseda.ac.jp/~oishi/LINKS/java-numerics.html を参考に。 Fortranで書かれたサブルーチンがあるのでしたら、Javaから呼び出す方法もあります。これだと速度低下はほとんどありません。 swig http://www.swig.org/doc.html などを使うこともできます。 私自身はRubyで数値演算をやっています。 narrayという行列計算ライブラリを使っていますが、最適化されていないFortranに比べて1桁程度遅くなります。プログラム作成の効率を考えると、普通はこの程度の速度がでれば十分です。ときどき速度が足りなときがあるのですが、その場合はCかFortranでボトルネックになる部分だけ(10~20行程度)書き、swigでライブラリ化しています。そのような必要があるときは、並列化かGPUを使う場合がほとんどですのでかなりの高速化を行っています。

monomei
質問者

補足

ご回答ありがとうございました。 定量的に比較してみました所、Fortranでデフォルトの最適化の場合で約10倍、最適化無しの場合でも2~3倍の速度差が有りました。 ライブラリや外部プログラムを使うのも手段ですが、その前にもう少し何とかならないかなと思いますので、もう少しトライしてみます。

関連するQ&A

  • JAVAの開発環境について

    JAVA初心者です。 サーバサイドのJAVAの開発を行います。 サーバはSun Solaris9で、クライアントは WindowsXPです。 Servletはサーバに格納して動作させるものですが、 このコーディング・コンパイルはWindowsで行って、 コンパイルが通ったものをサーバにコピーする、という方法で開発できるのでしょうか? それともサーバはSolarisなので、コーディングは全てSolarisで行わなければならないのでしょうか。 非常に初歩的な質問で申し訳ないですが、回答をお願いいたします。

    • ベストアンサー
    • Java
  • Java-Linux

     はじめまして、LINUX初心者です。 今、RedHat7.2(FTP版)を使っています。 Java言語を勉強したいので、SUNのサイトから、 J2SDK1.4.0をダウンロードし、/root/にあります。コンパイルしたい時には、 #/root/j2sdk1.4.0/bin/java HelloWorld.java  しかし、コンパイルする時に、 #java HelloWorld.java のようにしたいのですが、PATHの設定方法を教えてお願いします。

  • 言語別(C/C++,Java等)の計算速度の違いが知りたいです。

    言語別(C/C++,Java等)の計算速度の違いが知りたいです。 巡回セールスマン問題を解く(よさそうな解を見つける)プログラムを書くことになったのですが、言語が自由です。 オブジェクト指向言語で組もうと思っているんですが、C++、C#、Javaなどの言語のうち、計算速度が早いのはどれでしょうか? 順番も分かれば、教えてほしいです。 また、もしC言語で組めれば、やっぱりオブジェクト指向言語よりも早いのでしょうか? 大体でもよいので、分かる方いたら教えてください。 よろしくお願いします。

  • java3dが動かない

    javaでプログラミングをしています. WindowsXPでJava3Dを使って3Dのスタンドアローンで動くアプリケーション(javaアプレットではないもの)を作ろうと思っています. しかし,プログラムがコンパイルエラーになってしまいます. プログラム自体は書籍のCD-ROMについてきたものなのでバグは無いはずです. 以下に必要な情報を示します. ・インストールしたもの(java3Dの書籍付属のCD-ROMから)   jdk-1_5_0_11-windows-i586-p.exe   java3d-1_5_0-windows-i586.exe ・コンパイルエラーの内容   : パッケージ javax.media.j3d は存在しません。   : パッケージ javax.vecmath は存在しません。   : パッケージ com.sun.j3d.utils.universe は存在しません。   : パッケージ com.sun.j3d.utils.geometry は存在しません。 ・java3Dを用いないjavaプログラムは動作する

    • ベストアンサー
    • Java
  • java を Visual Studio でデバッグ

    java を Visual Studio でデバッグ java のプログラムを VS でステップ実行させながらデバッグすることってできるんでしょうか。 もしできるなら、どなたか、やり方をお教えください。VS2005 を使っています。 「VJ# プロジェクト」というものがあったので、「コレか?」と思って空の VJ# プロジェクトを作って、普段 jdk (SE) の javac にコンパイルさせている java プログラムのファイルを入れてみたのですが、エラーでまくりでビルドできませんでした。やっぱ、VJ# と java はちがうんですよね?きっと。 VS に限らず、「java のデバッグなら、コイツがオススメだぜ」というのがあったら、そちらを紹介して頂けるのもありがたいです。あまり高価な env は手が出ないと思いますが。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 基本情報のJAVAで聞きたいことがあります

     今回始めて受験するものですが、午前や午後対策に時間をとられすぎてJAVAの勉強をあまりしていません。  JAVAのレベルは試験に出るようなアルゴリズムで複雑なもの以外は大体コーディングできるんですが、オブジェクト指向について理解がとぼしく直線的なプログラムしか書けません。もうすぐ試験ですが他の午後問題だけでいまは頭はいっぱいです。そんなわけでJAVAの過去問には手をつけてません。いまのレベルで本番でJAVA問題がとけるのでしょうか。あと3週間でできる対策とは? それともし次回うけるとしたらCASLIIの方がいいのでしょうか。よろしくお願いします。

  • JAVA実行ができなくなった・・

    初心者です。 javaのバージョン1.5インストールし、しばらくコンパイル・実行ともにできていたんですが、 oracl10gをインストールしてから実行ができなくなってしました。 java -version で確認したところ 1.4.0になっていたので 実行時 じjava -version:1.5 Classname で実行試しました。 ですが、エラーで Unrecognized option: -version:1.5 Could not create the Java virtual mashine. となってしまいました。 これから何をすればいいか、わかりません。 javaの再インストールは試しました。 よろしくお願いします。

    • ベストアンサー
    • Java
  • Java コンパイル

    Javaの勉強を始めたばかりなのですが、コンパイルして実行する際には毎回コマンドプロンプトに(javac ファイル名.java)と(java ファイル名)を入力しないといけないのでしょうか? ちょっとした変更をして何回もコンパイルして試したい時なんかに何回も入力してやるのは面倒な気がして・・・ 普通こうやってやるものなのでしょうか? 教えてくださいm(_ _ )m

  • JAVA の特徴

    サンが開発したJava、Java2 がネットワーク言語としてスタンダードになっているようですがその理由についてご教示ください(当方素人同然のコンピュータ知識です)。 WIKIPEDIA などでは「Cをもとに開発され、ネットワークに適している」といった説明がなされていますが「なぜ」ネットワークに適しているのかが理解できません。 例えば FORTRAN なら「複雑な計算のサブルーチンに簡単に入れるコマンドがあるので技術計算に適する」といった浅学者でもスカッ!とわかるような説明がありがたいです(そもそもネットワーク言語なる概念がわかっていません)。

  • Fedora Core5にJavaを入れましたがコンパイル出来ません。

    Lnux初心者です。Fedora Core5にJavaを入れましたがコンパイル出来ません。 Javaのバージョンはj2sdk1.4.2_12とjdk1.5.0_08です。インストール確認も出来Pathには/home/****の.bash_profileにJAVA_HOME=/usr/java/j2sdk1.4.0_12 PATH=$PATH:$JAVA_HOME/bin CLASSPATH=.:$JAVA_HOME/lib/tools.jar export JAVA_HOME PATH CLASSPATH を追加しましたがコンパイル時にbash: javac: command not found と言うエラー表示がでます。どうにかLinuxでJavaをと考えているのですが、先に進めず困っています。Pathの通しかたがダメなのかどうかも判りません。どうかよろしくお願いします。

専門家に質問してみよう