5
$\begingroup$

I have problems to write parallel code in mathematica. Why is

candidates = {};
SetSharedVariable[candidates];

Do[
  ParallelDo[

   eq = RandomReal[] + RandomReal[];
    AppendTo[candidates, eq]

   , {j, 1, 1000}]
  , {i, 1, 10}]

slower than the non parallel version

candidates = {};
Do[
  Do[

   eq = RandomReal[] + RandomReal[];
    AppendTo[candidates, eq]

   , {j, 1, 1000}]
  , {i, 1, 10}]

?

$\endgroup$
  • $\begingroup$ I reverted your post to before the edit because it looks like a different question (like Henrik said in his comment). Note, however, that if you ask it in precisely such form it will be likely closed due to not enough info: you need to provide the minimal working example, not through some undefined functions into a piece of code that no one will be able to run and test. $\endgroup$ – corey979 Apr 11 at 13:54
  • 1
    $\begingroup$ See here mathematica.stackexchange.com/a/48296/12 I suggest you don't use SetSharedVariable until you get quite fluent in using the parallel tools. It effectively "unparallelizes" your code. $\endgroup$ – Szabolcs Apr 11 at 14:09
5
$\begingroup$

Because managing write access to shared memory is expensive: Subprocesses have to wait until they are granted write access (because another process uses that ressource).

Moreover, it is in general more efficient to use Parallel only upon the most outer loop construct.

By the way: Using Append and AppendTo are the worst methods to build a list, because they involve a copy of the full list each time another element is appended. Instead of complexity $O(n)$ for a list of $n$ elements, you get an implementation of complexity $O(n^2)$. Better use Table or, if you don't know how long the list is about to get, use Sow and Reap. Internal`Bag is a further option, and it is even compilable.

$\endgroup$
  • $\begingroup$ Thanks, that actually helped a lot. I just dont understand how to use Sow and Reap to avoid Append To be more specific: instead of ParallelDo I use now ParallelTable: eq = ParallelTable[ FNumeric[ SetPrecision[N[monlistnumeric[[i]] + monlistnumeric[[j]], 20], 10]] , {j, jj}]; FNumeric is a function, that returns either 0 or a value I want to store. I then do eq = DeleteCases[eq, 0]; candidates = Join[candidates, eq]; Is there a more efficient way to do this? $\endgroup$ – Matthias Heller Apr 11 at 12:55
  • 2
    $\begingroup$ @MatthiasHeller, you're welcome. How is this new code related to your post? You should consider a new post with your real problem and all relevant data. I may have a look. In general, depending on the details, there are various ways to perform the computation efficiently; these way might not use Parallel at all, but rather Compiled code. $\endgroup$ – Henrik Schumacher Apr 11 at 13:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.