并行的Lisp采样

时间:2012-03-05 19:11:25

标签: lisp common-lisp parallel-processing probability

假设我想从一些概率分布中抽取样本。在下面的例子中,我绘制了一些在0和1之间的均匀分布的rv,持续10000次。我不关心矢量中随机样本的排序,毕竟它们是随机的。

(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个核心,在一个核心中采样2500,最后将所有样本附加到一个单一的向量中。我之前已经问过Common Lisp Parallel Programming 这里。假设我是CL的总新手,一般编程应该是我解决这个问题的方法吗?我并不需要并行化的高级特性,我只想将采样的计算负荷平均分配给机器核心。如果您可以指出要进行并行化的一些步骤,或者我可以从中受益的一些在线教程,这将非常好。非常感谢。

1 个答案:

答案 0 :(得分:4)

您需要一个支持多核的Common Lisp实现。例如CCL,LispWorks和某些平台(IIRC)SBCL。

使用LispWorks 6.1及其多处理功能的简单示例如下。 它使用称为 barrier 的构造。进程等待障碍,直到有足够的进程到达。这意味着有足够的线程完成了它们的向量初始化。

启动线程的典型功能是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))