コア

2010-11-29 18 views
5

私は特に一般的な俳優にスカラ座に新たなんだと私の問題は、私が発見したオンラインリソースがそれをカバーしていないので、基本的なものを利用するために俳優を使用しました。コア

は私がN - コアマシン上で実行されるCPU集約型、簡単に並列化アルゴリズムを持っている(私は知らないN)。すべての利用可能なコアが問題に対処できるように、アクターでこれを実装するにはどうすればよいですか?

私が考える最初の方法は、(メートルが10,000のようないくつかのメディア数です)メートル個に簡単な休憩に問題だったとメートル俳優、各部分のための1つを作成し、各俳優にその少しを与えますピースと一緒に行こう。

どういうわけか、これは非効率的なとして私を襲いました。俳優の無数だけ無意味コンテキストを切り替え、いくつかのCPUの愛を待って、ぶらぶら...

は、その後、私は俳優のいくつかの小さな数を作る、と思った、とそれぞれいくつかの部分を養います。問題は、ピースのサイズが同じであると予想する理由がないため、1つのコアが停止し、他のコアがアイドルである間に、多くのタスクがキューに入れられている可能性があります。

私は俳優がビジーだったこれを知っていた、そして最終的にはこれが解決される問題であることを持っていることを実現スーパーバイザーの周りヌードル。この非常に一般的な問題に対処するための標準パターン(標準ライブラリでさえ)が必要です。助言がありますか?

答えて

8

は、俳優のimplementatonが含まAkka図書館、見てみましょう。 Dispatchers Moduleには、アクターからCPUスレッド(HawtDispatchベースのイベントドリブン)および/またはワークロードのバランスを取る(ワーク・スチール・イベント・ベース)など、さまざまなオプションがあります。

3

私は先物を考えなければなりません。実際には、スレッド数が最大に達したときに単にスレッドをキューに入れるスレッドプールが必要になる場合があります。

ここ

が先物を含む小さな例です:http://blog.tackley.net/2010/01/scala-futures.html

私はまた、あなたが本当に何もできないので、あなたは、コンテキストの切り替えにあまり注意を払っていないことを示唆しているが、基礎となる実装に依存しています。もちろん、経験則として、アクティブなスレッドを物理的なコアの周りに維持することがありますが、上記のように、これはFIFOキューを持つスレッドプールで処理できます。一般的または先物で俳優がプールのこの種で実装されている場合、私は知らない

NOTE。スレッド・プールの

、これを見て:http://www.scala-lang.org/api/current/scala/concurrent/ThreadPoolRunner.html

、多分この:http://www.scala-lang.org/api/current/scala/actors/scheduler/ResizableThreadPoolScheduler.html

幸運

EDIT

は先物を使用してコードのこの部分をチェックアウト:

import scala.actors.Futures._ 

object FibFut { 
    def fib(i: Int): Int = if (i < 2) 1 else fib(i - 1) + fib(i - 2) 
    def main(args: Array[String]) { 
    val fibs = for (i <- 0 to 42) yield future { fib(i) } 
    for (future <- fibs) println(future()) 
    } 
} 

これは、が結果を受け取る順番を決める(FIFOシステムを採用している通常のメールボックスシステム、つまり最も速い俳優が最初に結果を送信するのではなく)、先物についての非常に良い点を示しています。

0

重要なプロジェクトでは、私は一般的に、監督の俳優、それぞれが必要な作業を行うことができる作業者の俳優の集まり、および多数の作業を行います。私はこれをかなり頻繁に行っていますが、操作が毎回異なるため、(個人用の)ライブラリに入れたことはありません。また、オーバーヘッドはコーディングプロジェクト全体に比べてかなり小さいためです。

3

一般に、スレッドに結び付けられているもの(アクターごとに1つのスレッド)と1つ以上のスレッドを共有するものは、リソースを割り当てるスケジューラー/ディスパッチャーの後ろで動作します(=タスク/制御されたスレッドプールまたは単一のスレッドに対して着信メッセージを処理する)。

2番目のタイプの俳優 - イベント駆動俳優を使用するとします。なぜなら、それらのうちの10kを実行すると言いますからです。あなたが持っているイベントドリブン俳優の数が何千(何千から何百万)であっても、それらすべてが小さなスレッドプールがメッセージを処理するために戦うことになります。スケジューラは、固定スレッドプール(遅い)に対して10kアクターに送信されたメッセージを処理しようとするか、プール内に新しいスレッドを割り当てるかのいずれかを行います(プールが制限されていない場合)、危険です(最悪の場合、メッセージを処理するための10kスレッドが開始されます)。

イベントドリブンアクターは、短時間(理想的には非ブロッキング)タスクに適しています。 CPU集約型のタスクを扱う場合は、スケジューラー/ディスパッチャープール(イベント駆動型アクターを使用する場合)またはアクター自体(スレッドベースのアクターを使用する場合)のコア数を、最高のパフォーマンスを達成する。

あなたは、これが(コア数にディスパッチャプール内のスレッドの数を調整)を自動的に行うことにしたい場合は、それが以前に提案されたとして、あなたは、HawtDisaptch(またはそれがAkka implementationです)を使用してください:

は、

'HawtDispatcher'は HawtDispatchスレッドライブラリを使用します。 はlibdispatchのJavaクローンです。この種のディスパッチャ を持つすべての アクタは、固定サイズのスレッドプールである という単一のシステムワイドで実行されます。スレッドの の数は、ご使用のシステムで使用可能なコア数の と一致します。 ディスパッチャは、 プロデューサを送信者の順序で 人の俳優に配信します。

0

Be aware of actor starvation一般的な俳優のスレッドプールを利用すると終了します。私は自分のアルゴリズム - タスク所有のスレッドプールを使って、長時間実行される並行タスクの並列化を処理するだけでした。

0

今後のScala 2.9には、並列データ構造が含まれていることが予想されます。この構造では、自動的にこれを処理する必要があります。それは俳優を使用しませんが、それはあなたの問題のために考慮する何かかもしれません。

この機能はもともと2.8向けにリリースされましたが、次回のメジャーリリースまで延期されています。

最後ScalaDaysからのプレゼンテーションはここにある:

http://days2010.scala-lang.org/node/138/140