2011-09-29 111 views
4

作为一个玩具的例子,假设我们有一个名为'my_func'的函数(代码如下),它需要两个参数'n'和'p'。我们的函数'my_func'将生成一个随机矩阵'x',其中包含'n'行和'p'列,并且在运行时和内存使用中执行一些昂贵的操作,例如计算'x'的奇异值之和。 (当然,该功能是一个班轮,但我在这里拍摄的可读性。)向量化与R中的并行化

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

如果我们要计算“my_func,并将”的“N”的几个值,并为“每个值N“我们有几个值‘p’,然后向量化的功能,然后将其组合为‘my_func,并将’是直接的:

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 

注意,每次调用‘my_func,并将’可以是对于大十分缓慢” n'和'p'(首先尝试n = 1000和p = 2000)。

现在,在我的具有类似构造函数的实际应用中,“网格”中的行数比这里给出的大得多。因此,我试图更好地理解R中的矢量化。

第一个问题:在上面的例子中,对'my_func'的调用是否按顺序执行,以便在下次调用之前一次调用的内存使用量被垃圾收集?我经常使用矢量化,但从来没有停止问这个问题。

第二个问题:(这个问题可能取决于第一个问题)假设调用的数量足够大并且'my_func'足够慢,是否需要并行化?我假设是。我的real问题是:如果在每个调用中传递给它的'my_func'有相同的大矩阵,那么在此是否需要并行化?为了论证,假设矩阵被称为'y',具有1000行和5000列,并且被即时计算。当然,将矩阵'y'传递给每个并行节点会产生一些滞后。

我明白第二个问题的答案可能是“这取决于...”如果是这样的话,请让我知道,我会尽量给出更多的细节。

而且,我很欣赏的任何建议,意见或OMFG WTF N00B你有没有看到这个其他OBSCURE有些相关的讨论?? !!! 111oneone1

回答

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上的任务视图有进一步的指针。 R 2.14.0将于10月31日发布,将有一个新的“并行”程序包,其中包含multicoresnow的部分内容。

+0

感谢您的回复。我通过Rmpi并行使用了多达512个内核的foreach,并通过8核心盒上的多核。虽然它为并行计算提供了一个简单的界面,并且允许我为不同机器上的不同配置编写一次,但不知道引擎盖下发生了什么正在引起一些令人头疼的问题。 – ramhiser

+0

我经常使用* apply()系列,所以我会检查出mclapply。任何有8个核心的多台机器集群的想法?此外,下雪(甚至是降雪)是否可以轻松地编写代码,然后通过更改后端端口转到其他配置?看起来我有一些玩法要做。 – ramhiser

+0

Dirk - 将在Windows®上支持R 2.14.0中的“并行”功能? (请说是,请说是=) – SFun28