3
votes

Assume that I want to draw samples from some probability distribution. In the case below I draw some uniformly distributed rv's between 0 and 1 for 10000 times. I do not care about the ordering of the random samples in the vector, after all they are random.

(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)))

I have a multicore machine and I want to implement the above code in parallel. (i.e. assuming I have 4 cores, sampling 2500 in one core and at the end appending all samples in to one single vector. I have asked before about Common Lisp Parallel Programming here. Assuming that I am a total newbie in CL and programming in general what should be my approach to this problem? I do not require advanced characteristics in parallelization, I just want to distribute the computational load of the sampling to machine cores equally. If you can point out some steps to do for parallelization or some online tutorial stuff that I can benefit from that would be really nice. Thanks a lot in advance.

1

1 Answers

5
votes

You need a Common Lisp implementation which is multi-core capable. Examples are CCL, LispWorks and on some platforms (IIRC) SBCL.

A simple example using LispWorks 6.1 and its multiprocessing capabilities follows. It uses a construct called a barrier. Processes wait on a barrier until enough processes arrive. Here it means that enough threads have finished their vector initialization.

The typical function to start a thread is 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))