Common Lisp 并行采样

YBE*_*YBE 3 lisp parallel-processing probability common-lisp

假设我想从某个概率分布中抽取样本。在下面的例子中,我在 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)))
Run Code Online (Sandbox Code Playgroud)

我有一台多核机器,我想并行实现上面的代码。(即假设我有 4 个内核,在一个内核中采样 2500,最后将所有样本附加到一个向量中。我之前在 这里询问过Common Lisp 并行编程。假设我是 CL 和编程方面的新手我应该如何解决这个问题?我不需要并行化的高级特性,我只是想将采样的计算负载平均分配到机器核心。如果你能指出一些并行化的步骤或一些在线教程的东西我可以从中受益会非常好。非常感谢。

Rai*_*wig 5

您需要一个支持多核的 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))
Run Code Online (Sandbox Code Playgroud)