r-当使用mclapply时,每个单芯比其未并行版本慢



我正在学习R中的并行计算,我在实验中发现了这种情况。

简单地说,在下面的例子中,为什么t中的"user"的大多数值都小于mc_t中的值?我的机器有32GB的内存,2个CPU,共有4个内核和8个超线程。

system.time({t = lapply(1:4,function(i) {
m = matrix(1:10^6,ncol=100)
t = system.time({
m%*%t(m)
})
return(t)
})})

library(multicore)
system.time({
mc_t = mclapply(1:4,function(m){
m = matrix(1:10^6,ncol=100)
t = system.time({
m%*%t(m)
})
return(t)
},mc.cores=4)
})
> t
[[1]]
user  system elapsed
11.136   0.548  11.703
[[2]]
user  system elapsed
11.533   0.548  12.098
[[3]]
user  system elapsed
11.665   0.432  12.115
[[4]]
user  system elapsed
11.580   0.512  12.115
> mc_t
[[1]]
user  system elapsed
16.677   0.496  17.199
[[2]]
user  system elapsed
16.741   0.428  17.198
[[3]]
user  system elapsed
16.653   0.520  17.198
[[4]]
user  system elapsed
11.056   0.444  11.520

sessionInfo():

> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-pc-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8       LC_NAME=C
[9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base
other attached packages:
[1] multicore_0.1-7

澄清:很抱歉,我的描述可能有歧义。我知道,对于整个任务来说,并行仍然更快。然而,时间计数器只是用于计算的函数,mclapply中每个子进程的设置开销的时间没有被考虑在内。所以我仍然很困惑,为什么这个纯计算(即m%*%t(m))步骤慢了。

我想时间差异是由于内核之间的资源争用,可能是内存或缓存,特别是如果您的CPU有一个在内核之间共享的缓存。即使有足够的主内存,访问它也可能存在争用,导致性能不能随内核数量线性扩展。

请注意,如果R安装使用多线程数学库(如MKL或ATLAS),%*%操作符将使用多个内核。通过在此基础上使用多个进程,您可能会拥有比核心多得多的线程,从而影响性能。

并行算法的理论最佳加速计算为

S(n) = T(1) / T(n) = 1 / (P + (1 - P) / n)

其中T(n)是使用n个并行进程执行任务所花费的时间,p则是整个任务中严格串行的比例。利用这个公式,假设一个任务在一个处理器上执行需要10秒,让我们计算4个处理器的并行算法的理论上尽可能快的速度。

1 / (0.5 + (1-0.5)/4) = 1.6x

使用这些信息,我们可以说每个处理器都比单处理器版本的算法慢,因为速度不到4倍。但这就是它的工作原理。这种情况被称为阿姆达尔定律。Amdahl定律为我们提供了可能的最大速度估计,但它没有考虑间接费用。你可以在这里进一步阅读。

为了计算时间而不是加速率,我们使用公式

T(n) = T(1)*(P + (1-P)/n)

让我们计算一个任务在单个处理器上花费10秒的最佳运行时间。

T(4) = 10 * (0.5 + (1 - 0.5)/4) = 6.25

最新更新