2012-03-05 13 views
2

確率分布からサンプルを描きたいとします。以下のケースでは、10000回にわたって一様に分布したrvを0と1の間で描画します。私は無作為であるにもかかわらず、ベクトル内のランダムサンプルの順序については気にしません。一般的なLispのサンプリングを並列で行う

(setf my-vec (make-sequence 'vector 10000 :initial-element 0)) 
(loop :for i :from 0 :to 9999 :do 
    (setf (svref my-vec i) (random 1.0))) 

私はマルチコアマシンを持っており、上記のコードを並列に実装したいと考えています。 (すなわち、私は4つのコアを持っていると仮定して、1つのコアに2500をサンプリングし、最後にすべてのサンプルを1つのベクトルに追加することを前提としています)。この問題に対する私のアプローチですか?私は並列化の高度な特性を必要としません、私はちょうどサンプリングの計算負荷を均等に機械コアに分配したいです。あなたが並列化やオンラインチュートリアルのために行うべきいくつかのステップを指摘することができますそれは本当にいいだろうから恩恵を受けることができます。どうもありがとう事前に。

答えて

4

をあなたはマルチコア対応であるCommon Lispの実装を必要とする。例としては、CCL、LispWorksといくつかのプラットフォーム上で(IIRC)SBCLある。

LispWorks 6.1とそのマルチプロセッシング機能を使用した簡単な例を以下に示します。 バリアーと呼ばれる構成を使用しています。プロセスは、十分なプロセスが到着するまで障壁を待つ。ここでは、十分なスレッドがベクトルの初期化を完了したことを意味します。

スレッドを開始する典型的な機能はPROCESS-RUN-FUNCTIONです。

(defun make-random-vector (&key (size 10000) (n-threads 4)) 
    (let ((vector (make-sequence 'vector size :initial-element 0)) 
     (barrier (mp:make-barrier (1+ n-threads))) 
     (delta (truncate size n-threads))) 
    (loop for i below n-threads 
      do (mp:process-run-function 
       "init" 
       nil 
       (lambda (barrier vector start end) 
       (loop for i from start below end do 
         (setf (svref vector i) (random 1.0))) 
       (mp:barrier-wait barrier :pass-through t)) 
       barrier 
       vector 
       (* i delta) 
       (+ delta (* i delta)))) 
    (mp:barrier-wait barrier) 
    vector)) 
+1

これは素晴らしい例です。質問:各スレッドが同じ配列に書き込みを行っている減速b/cはありますか?スレッドごとに別々の配列を作成し、最後に結合した方が速いでしょうか? –

+1

@claytontstanley:間違いなく、試してみると意味があります。私はそれについて考えましたが、コードをあまりにも複雑にしたいとは考えていませんでした。この例では、作業を分割し、作業のスレッドを開始し、同期のための障壁を使用するという基本的な考え方が既に存在しています。 –

+0

@RainerJoswig、私はCCLを使用しています。 LispWorksと比較した場合、特に不利な点はありますか? CCLでの記述は、上記のコードと同じくらいコンパクトになりますか?どうもありがとう。 – YBE

関連する問題