R中的矢量化与并行化

时间:2011-09-29 23:52:38

标签: r vectorization

作为一个玩具示例,假设我们有一个名为' my_func' (下面的代码)有两个参数' n'并且' p'。我们的函数' my_func'将生成一个随机矩阵' x'与' n'行和' p'列和在运行时和内存使用中做一些昂贵的事情,例如计算' x'的奇异值的总和。 (当然,这个功能是一个单行,但我在这里为了可读性而拍摄。)

my_func <- function(n, p) {
  x <- replicate(p, rnorm(n))
  sum(svd(x)$d)
}

如果我们想要计算&#39; my_func&#39;对于&#39; n&#39;的几个值,以及&#39; n&#39;的每个值。我们有几个值&#39; p&#39;,然后对该函数进行矢量化,然后将这些组合应用于&#39; my_func&#39;很简单:

n <- 10 * seq_len(5)
p <- 100 * seq_len(10)
grid <- expand.grid(n = n, p = p)
my_func <- Vectorize(my_func)
set.seed(42)
do.call(my_func, grid)
[1]   98.61785  195.50822  292.21575  376.79186  468.13570  145.18359
[7]  280.67456  421.03196  557.87138  687.75040  168.42994  340.42452
[13]  509.65528  683.69883  851.29063  199.08474  400.25584  595.18311
[19]  784.21508  982.34591  220.73215  448.23698  669.02622  895.34184
[25] 1105.48817  242.52422  487.56694  735.67588  976.93840 1203.25949

请注意每次调用&#39; my_func&#39;对于大型的&#39; n来说,这可能会非常缓慢。和&#39; p&#39; (对于初学者来说,尝试n = 1000和p = 2000)。

现在,在我的实际应用程序中,使用类似构造的函数,&#39; grid&#39;中的行数。比这里给出的要大得多。因此,我试图更好地理解R中的矢量化。

第一个问题:在上面的示例中,调用了&#39; my_func&#39;按顺序执行,以便在下一次调用之前对一次调用中的内存使用情况进行垃圾回收?我经常使用矢量化但从未停止过问这个问题。

第二个问题:(这个问题可能取决于第一个问题)假设呼叫数量足够大并且“my_func”#39;是否足够慢,是否需要并行化?我假设是的。我的真实的问题是:如果相反的话,是否支持并行化&#39; my_func&#39;为每次通话都有相同的大矩阵传递给它吗?为了论证,假设矩阵被称为&#39; y&#39;,有1000行和5000列,并且是即时计算的。当然,通过矩阵&#39; y&#39;每个并行节点都会产生一些延迟。

我理解第二个问题的答案可能是&#34;这取决于...&#34;如果是这种情况,请告诉我,我会尝试提供更多细节。

此外,我感谢任何建议,反馈,或者你有没有看到过这个其他部分的相关讨论?!!! 111oneone1

1 个答案:

答案 0 :(得分:8)

第一个问题的答案显然是肯定的: R中的几乎所有默认是串行的。 (内部开始使用OpenMP的内容很少,但作为引擎的R可能仍然是单线程的。)

所以对于第二个问题:是的,请尝试一下。我没有使用Vectorize(),但我确实喜欢*apply()家族。使用lapply()解决它,然后加载multicore包并使用mclapply()在您拥有的核心上运行它。这是一个例子:

R> system.time(res <- lapply(1:nrow(grid), 
+                            function(i) my_func(grid[i,1],grid[i,2])))
   user  system elapsed 
  0.470   0.000   0.459 
R> system.time(res <- mclapply(1:nrow(grid), 
+                              function(i) my_func(grid[i,1], grid[i,2])))
   user  system elapsed 
  0.610   0.140   0.135 
R> 

注意现在经过的时间约为原始时间的29%(= 0.135 / 0.459)。

从这里你可以进一步推广跨多台机器的并行执行 - High-Performane Computing with R上的任务视图还有进一步的指示。 10月31日到期的R 2.14.0将有一个新的'并行'包,它结合了multicoresnow的部分内容。