2012-04-27 2 views
1

私は、私の脳をパラレル/並行プログラミング(Java)でラップしようとしています。私が読んでいるチュートリアルではカバーされていないようないくつかのファンダメンタルズを諦めています。並列プログラミングはよりグリッド化されているかクラスタ化されていますか?

「マルチスレッド」または「並列/並行プログラミング」について言及すると、大きな問題を抱えてそれを多くのスレッドに広げていること、または最初に明示的に小さなサブコンポーネントに分解していることを意味します。問題を解決し、各サブ問題をスレッドに渡しますか?

例えば、EndWorldHungerTask implements Runnableがあり、タスクがいくつかの大きな問題を抱えているとします。この「同時」または「マルチスレッド」、我々が通過するこのEndWorldHungerTaskを行うために

public class EndWorldHungerTask implements Runnable { 

    public void run() { 
     for(int i = 0; i < 100000000; i++) 
      someReallyExpensiveOperation(); 
    } 
} 

:その目的を完了するためには、いくつかの本当に重い物を持ち上げる、と言うを行うには億回を持っていますたとえば、100人のワーカースレッド(100人の作業者のそれぞれが、アクティブになるときにJVMによって指示され、次の繰り返し/ someReallyExpensiveOperation()コールで作業する)、または100人の作業者のそれぞれがループのさまざまな部分を繰り返す/作業する予定ですか?どちらの場合も、100人の労働者のそれぞれは、100万回の反復だけです。

しかし、最初のパラダイムの下では、Javaは実行するタイミングを各スレッドに伝えています。第2の下では、開発者は手動で(コード内で)問題を事前にパーティション化し、各サブ問題を新しいスレッドに割り当てる必要があります。

私は、Javaの土地でどのように "通常行われている"かを尋ねています。そして、この問題だけでなく、一般的に。

答えて

1

私はJavaの土地でどのように "通常行われている"かと尋ねています。そして、この問題だけでなく、一般的に。

これは、現在の仕事に大きく依存します。

Javaの標準的なパラダイムは、あなた自身をチャンクに分割する必要があるということです。これらのチャンクを複数のスレッド/コアに分散させることは別の問題であり、そのためのさまざまなパターン(キュー、スレッドプールなど)が存在します。

複数のコアを自動的に使用して、forループ(たとえば、OpenMP)を実行できるフレームワークが存在することは興味深いことです。しかし、私はJavaのためのそのようなフレームワークを認識していません。

最後に、大量の作業を行う低レベルのライブラリで複数のコアを使用できる場合があります。このような場合、上位レベルのコードはシングルスレッドのままで、マルチコアハードウェアの恩恵を受けることができます。 1つの例は、MKLを使用した数値コードです。

0

通常、各スレッドは1つのタスクフォームを開始して終了する必要があります。タスクの半分を終了してからそのスレッドの実行を停止し、別のスレッドを「終了」してジョブを終了します。 Javaは、もちろん、この種のスレッド同期のためのツールを提供しますが、タスクが別のタスクに依存している場合には本当に使用されます。

ほとんどの場合、いくつかのタスクからなる大きな問題があります。このタスクを同時に実行できる場合は、スレッドを生成してこのタスクを実行することが理にかなっています。スレッドの作成にはオーバーヘッドがあります。したがって、すべてのタスクがシーケンシャルであり、他のタスクが終了するまで待たなければならない場合は、複数のスレッドを生成するのに有益ではなく、メインスレッドをブロックしないように。

1

私たちは、「マルチスレッド」、または「並列/並行プログラミング」について話す、それは私たちは大きな問題を取り、多くのスレッド上で、それを広げ、あるいは我々が最初に明示的に小さいに分解されている意味していサブ問題、そして各サブ問題をそれ自身のスレッドに渡すか?

私はこれが問題に大きく依存していると思います。同じコードを使用して1000秒または何百万回もコールする同じタスクがある場合があります。これはExecutorSerivce.submit()タイプのパターンです。ファイルから何百万もの行があり、各行にいくつかの処理メソッドを実行しています。私はこれがあなたの「多くのスレッドに広がっている」タイプの問題だと思います。これは、単純なスレッドモデルで機能します。

しかし、問題空間が多数の不均一なタスクで構成されている場合があります。時には、いくつかのバックグラウンド・キープ・アライブを処理するために単一のスレッドを生成し、他の時にスレッド・プールをいくつかのキューを処理するためにここに作成することがあります。通常、問題の範囲が大きくなるほど、並行性モデルが複雑になり、より多くの異なるタイプのプールとスレッドが使用されます。私はこれがあなたの「より小さなサブ問題に分解する」タイプだと思う。これは、「同時」または「マルチスレッド」にするためには

、我々は100人の労働者のそれぞれがアクティブになるようにすると、JVMによって言われて100件のワーカースレッド(、たとえば、このEndWorldHungerTaskを通過すると、次のiteration/someReallyExpensiveOperation()呼び出しで作業します)、または100人の作業者のそれぞれがループのさまざまな部分/作業完了予定を繰り返し実行するように手動または明示的にリファクタリングしますか?どちらの場合も、100人の労働者のそれぞれは、100万回の反復だけです。

あなたのケースでは、世界の飢えを解決する方法(あなたの類推を使用する方法)は、スレッドコードのセットではわかりません。私は、あなたが「より小さなサブ問題に分解しなければならない」と考えています。これは、私が上で説明した後者のケースに対応します。異なるコードを実行する一連のスレッド。サブソリューションの中にはスレッドプールで実行できるものと、スレッドごとに別々のコードを実行するものがあります。

私はJavaの土地でどのように "通常行われている"かと尋ねています。そして、この問題だけでなく、一般的に。

「通常」は問題とその複雑さに大きく依存します。私の経験では、通常、私は可能な限りExecutorService構成を使用します。しかし、まともなサイズの問題があれば、さまざまなスレッドプール、Springタイマースレッド、カスタムのワンスレッドスレッドタスク、プロデューサ/コンシューマモデルなどを見つけることができます。

0

"マルチスレッド" <>「並行/並行プログラミング」。

マルチスレッドアプリケーションは、プリエンプティブマルチタスクの高いI/Oパフォーマンスを利用するために書かれていることがよくあります。 Webクローラー/ダウンローダーの例があります。マルチスレッドクローラは、CPUコアが1つしかないボックスで実行している場合でも、通常、単一スレッドバージョンよりも遥かに優れています。サイトのアドレスを取得し、サイトに接続し、ページをダウンロードし、ディスクファイルに書き込むためのDNSクエリの動作は、ほとんどCPUを必要としないが多くのIO待機を必要とする操作です。したがって、これらの避けられない待ちの多くは、多くのスレッドによって並行して実行できます。 DNSクエリーが到着すると、HTTPクライアントが接続されるか、ディスク操作が完了すると、要求したスレッドは準備完了/実行され、次の操作に進むことができます。

アプリの大部分は、主にマルチスレッド化されているためです。だからこそ私が書いているボックスには、98のプロセス(うち94スレッドは1つ以上のスレッドを持つ)、1360スレッド、3%のCPU使用率があります.CPUをコアに分割することとはほとんど関係がありません。パフォーマンス。

並列/並列プログラミングは、実際には複数のCPUコアで実行できます。コアを介して配布するための大規模なパッケージに分解できるCPUを大量に使用するアプリケーションの場合、コア数に近づくためのスピードアップが可能です。

当然ながら、I/OバインドされたWebクローラは、割り込み/ドライバのオーバーヘッドが全体的なパフォーマンスに与える影響がより小さいため、より多くのコアを持つボックスでパフォーマンスが向上する傾向がありますが、あまりにも良い。

EndWorldHungerタスクで利用可能な作業者の数が、作物が成長するのを待っている場合は、問題はありません。

関連する問題