5

私は、大量のデータに対して非常に計算量の多い Ruby プログラムの最適化を検討してきました。私は C を知らず、Ruby を選択しました (私もそれをよく知っているわけではありません)。実行にかかる時間は別として、結果には非常に満足しています。これは大量のデータであり、お金をかけずに、自分のシステム リソースを確実に最大化するために何ができるかを知りたいです。

基本的な Ruby プログラムを実行する場合、単一のプロセッサを使用しますか? プロセッサにタスクを明確に割り当てていない場合、Ruby は私のプログラムを読み取らず、魔法のように各プロセッサをロードして、プログラムを可能な限り高速に完了しませんか? 私はないと仮定しています...

Ruby の高速化について少し読んだことがありますが、別のスレッドで、Ruby は真のマルチスレッドをサポートしていないことを読みました (ただし、JRuby はサポートしていると書かれていました)。しかし、プログラムを 2 つのチャンクに「分割」して、別々のインスタンスで実行し、これらを並行して実行するとしたら、これら 2 つのチャンクは 2 つの別々のプロセッサで自動的に実行されるのでしょうか? 4 つのプロセッサがあり、4 つのシェルを開いて、プログラムの 4 つの別々の部分 (1/4) を実行した場合、1/4 の時間で完了するでしょうか?

アップデート

コメントを読んだ後、JRuby を試してみることにしました。アプリの移植はそれほど難しくありませんでした。「peach」はまだ使っていませんが、JRuby で実行するだけで、アプリの実行時間が 1/4 になります!!! 非常識。そんなに変化があるとは思っていませんでした。今すぐ .peach を試してみて、それがどのように改善されるかを見てみましょう。あの後押しは未だに信じられない。

アップデート #2

桃を試してみました。時間をさらに 15% 削ることになりました。したがって、JRuby に切り替えて Peach を使用することは間違いなく価値がありました。

みんな、ありがとう!

4

4 に答える 4

4

JRuby とpeach gem を使えば、これほど簡単なことはありません。をに置き換えるだけ.each.peach、ほら、並列に実行されます。また、生成されるスレッドの数などを正確に制御するための追加オプションもあります。私はこれを使用しましたが、うまく機能します。

n倍近くのスピードアップが得られます。ここで、nは使用可能な CPU/コアの数です。スレッドの最適な数は、CPU/コアの数よりもわずかに多いことがわかりました。

于 2012-11-12T22:50:23.800 に答える
2

他の人が言っているように、ruby(ほとんどの人が使用するもの)のMRI実装はネイティブスレッドをサポートしていません。したがって、MRI実装を使用してより多くのスレッドを起動することにより、CPUコア間で作業を分割することはできません。

ただし、プロセスがIOバウンドである場合(たとえば、ディスクまたはネットワークアクティビティによって制限されている場合)、複数のMRIスレッドの恩恵を受ける可能性があります。

一方、JRubyはネイティブスレッドをサポートしています。つまり、スレッドを使用してCPUコア間で作業を分割できます。

しかし、すべてが失われるわけではありません。MRI(および他のすべてのruby実装)を使用すると、プロセスを使用して作業を分割できます。

Process.forkこれは、たとえば次のように使用して実行できます。

Process.fork {
  10.times {
    # Do some work in process 1
    sleep 1
    puts "Hello 1"
  }
}

Process.fork {
  10.times {
    # Do some work in process 2
    sleep 1
    puts "Hello 2"
  }
}

# Wait for the child processes to finish
Process.wait

を使用forkすると、CPUコア間で処理が分割されるため、スレッドなしで動作できる場合は、個別のプロセスが1つの方法です。

于 2012-11-12T20:14:42.687 に答える
0

ルビーは素晴らしいですが、実行速度で知られていません。そうは言っても、コメントに記載されているように、入力を同じサイズのチャンクに分割できる場合は、プログラムのn個のインスタンスを起動できるはずです。ここでnはコアの数であり、OSはすべてのコアを使用するように注意してください。

最良の場合、1 / nの時間で実行されますが、メモリなどのシステムの一部をプロセス間で共有する必要があり、プロセス間の競合が原因で発生する可能性があるため、この種のことを正確に行うのは難しい場合があります。直線的に拡大縮小しないでください。分割が簡単な場合は、試してみます。同じプログラムを2回実行して、実行にかかる時間を確認することもできます。1つを実行するのに、2つを実行するのと同じ時間がかかる場合は、すべて設定されている可能性があります。データを分割して、それ。

jrubyといくつかのスレッドを試してみるとおそらく役立つでしょうが、それはかなりの複雑さを追加します。(スレッドについて学ぶのはおそらく良い言い訳になるでしょう。)

于 2012-11-12T20:09:55.180 に答える
0

通常、スレッド化は Ruby の弱点の 1 つと考えられていますが、使用する Ruby の実装によって異なります。

さまざまなスレッド モデルに関する非常に優れた記事は、" Does ruby​​ has real multithreading? " です。

私の経験と、このことについてよく知っている人々から集めた情報から、Ruby 実装を選択する場合は、JRuby が最適なようです。ただし、Ruby を学習している場合は、JVM を使用する場合に一般的な選択肢である Erlang や Clojure などの別の言語を選択することをお勧めします。

于 2012-11-12T20:03:37.297 に答える