10

私は、並行して進めることができる容易に分離可能な部品を備えた科学的アプリケーションに取り組んでいます。したがって、これらの部分をそれぞれの実行に独立したスレッドとして記述しましたが、スレッドに分割する標準的な理由(つまり、終了コマンドなどをブロックしない)ではないようです。

いくつかの質問:

これは実際に標準のマルチコアデスクトップで何かを購入しますか?つまり、現在のJVMがある場合、スレッドは実際には別々のコアで実行されますか、それとも何か他のことをする必要がありますか?

すべてのスレッドによって読み取られる(書き込まれることはありませんが)オブジェクトはほとんどありません。それに関する潜在的な問題?それらの問題の解決策は?

実際のクラスターの場合、スレッドをさまざまなノードに分散するフレームワークを推奨して、自分で管理する必要がないようにすることはできますか(存在する場合)。明確化:これは、スレッドを個々のノードのタスクに自動的に変換するもの、またはクラスター全体を単一のJVMのように見せるもの(つまり、アクセス可能なプロセッサーにスレッドを送信できるもの)などを意味します。基本的に、並列化をアルゴリズムに組み込んだことを考えると、クラスターに便利な方法で並列化を実装します。私の側では最小限の仕事をします。

ボーナス:ほとんどの評価は、関連するセットを取得するためのキーからのマッピングを使用したセット比較(たとえば、和集合、共通部分、含む)で構成されます。私はFORTRAN、C、およびC ++(最初の科学計算の学期、および10年前の他の2つのHS APクラス)の経験が限られています-並列化のどのような速度/容易さの向上は、私がこれらの言語の1つでのJavaフロントエンドからアルゴリズムバックエンドへの変換。これらの言語でこれらの操作を実装することで、私の経験レベルではどのような問題が発生する可能性がありますか?

4

3 に答える 3

8
  • はい、独立したスレッドを使用すると、通常の JVM で複数のコアが使用されます。何もする必要はありません。

  • 何かが読み取られるだけの場合は、複数のスレッドで読み取っても問題ありません。問題のオブジェクトを不変にすることができれば (決して変更されないことを保証するため)、それはさらに良いことです

  • どのような種類のクラスタリングを検討しているのかはわかりませんが、Hadoopを確認することをお勧めします。分散コンピューティングは、スレッドではなくタスクを分散することに注意してください(通常はとにかく)。

于 2009-10-07T17:05:10.103 に答える
5

マルチコアの使用

Java ランタイムは従来、使用可能なすべてのプロセッサとコアで同時に実行されるようにスレッドをスケジュールします。これを制限することは可能だと思いますが、余分な作業が必要です。デフォルトでは、制限はありません。

不変オブジェクト

読み取り専用オブジェクトの場合、メンバー フィールドを として宣言しますfinal。これにより、オブジェクトの作成時に割り当てられ、変更されないことが保証されます。フィールドが ではない場合、final作成後に変更されていなくても、マルチスレッド プログラムで「可視性」の問題が発生する可能性があります。これにより、あるスレッドによって行われた割り当てが別のスレッドから見えなくなる可能性があります。

複数のスレッドによってアクセスされる変更可能なフィールドは、宣言volatileするか、同期によって保護するか、またはその他の同時実行メカニズムを使用して、変更がスレッド間で一貫して表示されるようにする必要があります。

分散コンピューティング

Java でこのような性質の分散処理に最も広く使用されているフレームワークは、Hadoop と呼ばれます。map-reduceと呼ばれるパラダイムを使用します。

ネイティブ コードの統合

他の言語と統合する価値はほとんどありません。適応型のバイトコードからネイティブへのコンパイラーにより、Java はすでに幅広いコンピューティング タスクで非常に高速です。実際のテストを行わずに別の言語の方が高速であると仮定するのは誤りです。また、JNI を使用した「ネイティブ」コードとの統合は非常に面倒で、エラーが発生しやすく、複雑です。JNA のような単純なインターフェースを使用すると非常に遅くなり、パフォーマンスの向上がすぐに失われます。

于 2009-10-07T17:21:31.753 に答える
1

一部の人々が言っ​​たように、答えは次のとおりです。

  1. コアのスレッド - はい。Java は長い間、ネイティブ スレッドをサポートしてきました。ほとんどの OS は、お使いの CPU に自動的にスケジュールされるカーネル スレッドを提供しています (実装のパフォーマンスは OS によって異なる場合があります)。

  2. 簡単な答えは、一般的に安全だということです。より複雑な答えは、スレッドがアクセスできるようになる前に、オブジェクトが実際に作成および初期化されていることを確認する必要があるということです。これは、次の 2 つの方法のいずれかで解決されます。

    • シングルトン (および遅延クラス読み込み) を使用して、クラス ローダーに問題を解決させます。

      public class MyImmutableObject
      {
          private static class MyImmutableObjectInstance {
              private static final MyImmutableObject instance = new MyImmutableObject();
          }
          public MyImmutableObject getInstance() {
              return MyImmutableObjectInstance.instance;
          }
      }
      
    • 取得/解放セマンティクスを明示的に使用して、一貫したメモリ モデルを確保します。

      MyImmutableObject foo = null;
      volatile bool objectReady = false;
      
      // initializer thread:
      ....
      /// create & initialize object for use by multiple threads
      foo = new MyImmutableObject();
      foo.initialize();
      
      // release barrier
      objectReady = true;
      
      // start worker threads
      public void run() {
         // acquire barrier
         if (!objectReady)
             throw new IllegalStateException("Memory model violation");
      
         // start using immutable object foo
      }
      

    後者のケースを実行するために Java のメモリ モデルをどのように活用できるか、頭の中で思い出すことはできません。私の記憶が正しければ、volatile 変数への書き込みはリリース バリアに相当し、volatile 変数からの読み取りは取得バリアに相当すると思います。また、オブジェクトとは対照的にブール値を揮発性にする理由は、メモリモデルの制約により揮発性変数のアクセスがより高価になるためです-したがって、ブール値によりメモリモデルを強制でき、オブジェクトアクセスを実行できますスレッド内でははるかに高速です。

  3. 前述のように、あらゆる種類の RPC メカニズムがあります。リモート ターゲットでコードを実行するためのネイティブ アプローチである RMI もあります。より適切な、より完全なソリューションを提供する Hadoop のようなフレームワークもあります。

  4. ネイティブコードを呼び出すのはかなり醜いです.SunはJNIを醜く複雑な混乱にすることで使用を本当に思いとどまらせていますが、それは可能です. JNI を気にせずにネイティブの動的ライブラリをロードおよび実行するための商用 Java フレームワークが少なくとも 1 つあることは知っています (無料または OSS プロジェクトがあるかどうかはわかりません)。

幸運を。

于 2009-10-07T17:40:29.423 に答える