lmj / lparallel

Parallelism for Common Lisp
http://lparallel.org
BSD 3-Clause "New" or "Revised" License
244 stars 29 forks source link

[help] pdotimes with side effects can leads to inaccurate results #39

Closed Inc0n closed 4 years ago

Inc0n commented 4 years ago

I would like to add parallelism to my project, which utilizes some side effects The following snippet is used to demonstrate how this can leads to inaccurate results.

> (defparameter ns 100)
> (let ((col-acc 0.0))
     (lparallel:pdotimes (i ns)
       (declare (ignore i))
       (incf col-acc 1.0))
    col-acc)

Running the above script, woud sometimes result in something that is not 100.0 (the expected)

81.0

I would like to know if this is doable with lparallel.

However, I do see an alternative approach, is to pmap times into list of data, then preduce to summarize it, since i am dealing with number of times as oppose to list of data. But i would want to avoid creating a list of range from 0 to ns to feed into pmap, because once ns become even bigger, 1000 for example, the overhead might be big enough to slow this procedure down, especially if it is called for thousands of times.

luismbo commented 4 years ago

Have a look at atomic-incf https://github.com/Shinmera/atomics but it's a bad solution since you won't be parallelizing anything. preduce sounds like the way to go although it's hard to tell from such a toy example. HTH

mdbergmann commented 4 years ago

Yeah, your incf should be serialized, or locked because it's not thread-safe. You can also look at https://stmx.org to 'protect' your col-acc.

Inc0n commented 4 years ago

Thanks for pointing me in the right direction. And the following is the lock I use for the current solution for this problem.

bt:make-lock
bt:with-lock-held