Note that there are some explanatory texts on larger screens.

plurals
  1. POProblems using foreach parallelization
    primarykey
    data
    text
    <p>I'm trying to compare parallelization options. Specifically, I'm comparing the standard <code>SNOW</code> and <code>mulitcore</code> implementations to those using <code>doSNOW</code> or <code>doMC</code> and <code>foreach</code>. As a sample problem, I'm illustrating the central limit theorem by computing the means of samples drawn from a standard normal distribution many times. Here's the standard code:</p> <pre><code>CltSim &lt;- function(nSims=1000, size=100, mu=0, sigma=1){ sapply(1:nSims, function(x){ mean(rnorm(n=size, mean=mu, sd=sigma)) }) } </code></pre> <p>Here's the <code>SNOW</code> implementation:</p> <pre><code>library(snow) cl &lt;- makeCluster(2) ParCltSim &lt;- function(cluster, nSims=1000, size=100, mu=0, sigma=1){ parSapply(cluster, 1:nSims, function(x){ mean(rnorm(n=size, mean=mu, sd=sigma)) }) } </code></pre> <p>Next, the <code>doSNOW</code> method:</p> <pre><code>library(foreach) library(doSNOW) registerDoSNOW(cl) FECltSim &lt;- function(nSims=1000, size=100, mu=0, sigma=1) { x &lt;- numeric(nSims) foreach(i=1:nSims, .combine=cbind) %dopar% { x[i] &lt;- mean(rnorm(n=size, mean=mu, sd=sigma)) } } </code></pre> <p>I get the following results:</p> <pre><code>&gt; system.time(CltSim(nSims=10000, size=100)) user system elapsed 0.476 0.008 0.484 &gt; system.time(ParCltSim(cluster=cl, nSims=10000, size=100)) user system elapsed 0.028 0.004 0.375 &gt; system.time(FECltSim(nSims=10000, size=100)) user system elapsed 8.865 0.408 11.309 </code></pre> <p>The <code>SNOW</code> implementation shaves off about 23% of computing time relative to an unparallelized run (time savings get bigger as the number of simulations increase, as we would expect). The <code>foreach</code> attempt actually <strong>increases</strong> run time by a factor of 20. Additionally, if I change <code>%dopar%</code> to <code>%do%</code> and check the unparallelized version of the loop, it takes over 7 seconds.</p> <p>Additionally, we can consider the <code>multicore</code> package. The simulation written for <code>multicore</code> is</p> <pre><code>library(multicore) MCCltSim &lt;- function(nSims=1000, size=100, mu=0, sigma=1){ unlist(mclapply(1:nSims, function(x){ mean(rnorm(n=size, mean=mu, sd=sigma)) })) } </code></pre> <p>We get an even better speed improvement than <code>SNOW</code>:</p> <pre><code>&gt; system.time(MCCltSim(nSims=10000, size=100)) user system elapsed 0.924 0.032 0.307 </code></pre> <p>Starting a new R session, we can attempt the <code>foreach</code> implementation using <code>doMC</code> instead of <code>doSNOW</code>, calling</p> <pre><code>library(doMC) registerDoMC() </code></pre> <p>then running <code>FECltSim()</code> as above, still finding</p> <pre><code>&gt; system.time(FECltSim(nSims=10000, size=100)) user system elapsed 6.800 0.024 6.887 </code></pre> <p>This is "only" a 14-fold increase over the non-parallelized runtime.</p> <p>Conclusion: My <code>foreach</code> code is not running efficiently under either <code>doSNOW</code> or <code>doMC</code>. Any idea why?</p> <p>Thanks, Charlie</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload