7

私は現在、データベースから大量のデータをロードし、状況に応じてさまざまな計算によってはるかに小さなセットに削減する 1 つのモジュールを持つアプリケーションを設計しています。

より集中的な操作の多くは決定論的に動作し、並列処理に適しています。

データベースから到着する多数のデータチャンクを反復処理するループがあり、それぞれが副作用なしで決定論的関数を呼び出す場合、プログラムが関数が戻るのを待たずに設定するようにするにはどうすればよいですか次の呼び出しが行われるので、それらを並行して処理できますか? 原則を実証するための単純なアプローチは、今のところ私に適しています。

私は Google の MapReduce の論文を読みました。全体的な原則をさまざまな場所で使用できますが、今のところ、大規模なクラスターをターゲットにすることはしません。バージョン 1.0 の単一のマルチコアまたはマルチ CPU マシンになる予定です。 . そのため、現在、ライブラリを実際に使用できるかどうか、または自分でレベルを下げた基本バージョンを作成する必要があるかどうかはわかりません。

私は設計プロセスの初期段階にあり、これまでのところ言語として C 言語 (速度が重要な部分) と Python (生産性が重要な部分) をターゲットにしています。やむを得ない理由があれば乗り換えるかもしれませんが、今のところ自分の選択に満足しています。

現在のチャンクを処理するよりもデータベースから次のチャンクを取得する方が時間がかかり、プロセス全体が I/O バウンドになる可能性があるという事実を認識していることに注意してください。ただし、現時点ではそうではなく、実際には db クラスターまたはメモリ キャッシュなどを使用して、この時点で I/O バウンドにならないようにします。

4

9 に答える 9

3

まだ Python を使用する予定がある場合は、Processingを参照してください。並列計算にスレッドではなくプロセスを使用し (Python GIL により)、「作業項目」を複数のプロセスに分散するためのクラスを提供します。プール クラスを使用すると、次のようなコードを記述できます。

import processing

def worker(i):
    return i*i
num_workers = 2
pool = processing.Pool(num_workers)
result = pool.imap(worker, range(100000))

これは、呼び出しをプロセスに分散する itertools.imap の並列バージョンです。プールの apply_async メソッドを使用して、遅延結果オブジェクトをリストに保存することもできます。

results = []
for i in range(10000):
    results.append(pool.apply_async(worker, i))

詳細については、Pool クラスのドキュメントを参照してください。

落とし穴:

  • 処理には fork() を使用するため、Win32 では注意が必要です。
  • プロセス間で転送されるオブジェクトはピクル可能である必要があります
  • ワーカーが比較的高速な場合は、チャンクサイズ、つまり 1 つのバッチでワーカー プロセスに送信される作業項目の数を微調整できます。
  • processing.Pool はバックグラウンド スレッドを使用します
于 2008-09-15T19:57:34.130 に答える
3

.net がオプションである場合、彼らはParallel Computingに多くの労力を費やしています。

于 2008-09-11T14:58:23.007 に答える
3

物理的に別のマシンを用意しなくても、Google のMapReduceからアルゴリズムを実装できます。これらの「マシン」のそれぞれを「スレッド」と考えてください。スレッドは、マルチコア マシンに自動的に分散されます。

于 2008-09-11T14:58:58.920 に答える
2

ここで何かが欠けているかもしれませんが、これは pthreads を使用するとかなり簡単に思えます。

N 個のスレッドを含む小さなスレッドプールをセットアップし、1 つのスレッドですべてを制御します。

マスター スレッドは、単純に次のようなループを実行します。

  1. DBからデータチャンクを取得
  2. 次の空きスレッドを検索 空きスレッドがない場合は待機
  3. ワーカー スレッドにチャンクを渡す
  4. 戻って DB から次のチャンクを取得する

その間、ワーカー スレッドは座って次のことを行います。

  1. 自分を無料としてマークする
  2. マスト スレッドがデータのチャンクを提供するのを待ちます
  3. データのチャンクを処理する
  4. 自分を再びフリーとしてマークする

これを実装する方法は、2 つのミューテックス制御配列と同じくらい簡単です。1 つは作業中のスレッド (スレッドプール) を含み、もう 1 つは対応する各スレッドがフリーかビジーかを示します。

好みに合わせて N を微調整します...

于 2008-09-12T00:29:38.860 に答える
2

それをサポートするコンパイラを使用している場合は、特定のループが並列化されるようにコードに注釈を付ける方法について、http://www.openmp.orgを参照することをお勧めします。

それはさらに多くのことを行い、非常に役立つかもしれません.

たとえば、彼らの Web ページでは、gcc4.2 が openmp をサポートすると報告しています。

于 2008-09-11T17:34:59.997 に答える
0

単一のサーバーでマルチスレッド/マルチコアを使用するための MapReduce ライブラリを開発しました。すべてがライブラリによって処理され、ユーザーは Map と Reduce を実装するだけです。Boost ライブラリとして位置付けられていますが、正式なライブラリとしてはまだ受け入れられていません。http://www.craighenderson.co.uk/mapreduceをチェックしてください

于 2009-10-28T13:03:20.313 に答える
0

同じスレッド プールが Java で使用されます。ただし、スレッドプール内のスレッドはシリアライズ可能で、他のコンピューターに送信され、デシリアライズされて実行されます。

于 2009-03-10T12:00:41.313 に答える
0

Apple の Grand Central Dispatch のオープン ソース実装であるlibdispatchのコードを調べることに興味があるかもしれません。

于 2009-10-28T13:09:33.423 に答える
0

Intel の TBB または boost::mpi にも興味があるかもしれません。

于 2009-10-28T13:26:44.020 に答える