我正在学习R中的并行计算,我在实验中发现了这一点。
简而言之,在以下示例中,为什么t
中“用户”的大多数值都小于mc_t
中的值?我的机器有32GB内存,2个cpus,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)
)步骤较慢。
答案 0 :(得分:1)
我猜测时间差异是由于内核之间的资源争用,可能是内存或缓存,特别是如果你的CPU有一个在内核之间共享的缓存。即使存在大量主存储器,也可能存在争用访问它,导致性能不随核心数量线性扩展。
请注意,如果R安装使用多线程数学库(如MKL或ATLAS),%*%
运算符将使用多个核心。通过使用多个进程,您可以拥有比核心更多的线程,从而损害您的性能。
答案 1 :(得分:0)
并行算法的理论上可能的最佳加速计算为
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倍。但这就是它的工作原理。这种情况称为阿姆达尔定律。阿姆达尔定律为我们提供了最大可能加速的估计,并且不考虑间接费用。您可以进一步阅读here。
要计算时间而不是加快速度,我们使用公式
T(n) = T(1)*(P + (1-P)/n)
让我们计算在单个处理器上花费10秒的任务的最佳运行时间。
T(4) = 10 * (0.5 + (1 - 0.5)/4) = 6.25