[英]When (if ever) should I tell R parallel to not use all cores?
我一直在使用以下代码:
library(parallel)
cl <- makeCluster( detectCores() - 1)
clusterCall(cl, function(){library(imager)})
然后我有一个包装函数,看起来像这样:
d <- matrix #Loading a batch of data into a matrix
res <- parApply(cl, d, 1, FUN, ...)
# Upload `res` somewhere
我在笔记本电脑上测试了8核(4核,超线程)。 当我在50,000行,800列矩阵上运行它时,花了177.5s来完成,并且在大多数情况下,这7个核心保持在接近100%的位置(根据顶部),然后在最后15个地方停在那里大概几秒钟,我想这就是结果。 根据system.time()
,用户时间为14秒,因此匹配。
现在,我在36核c4.8xlarge EC2上运行,并且我看到它几乎全部时间都花在了100%的一个核上。 更精确地说:在使用所有内核的情况下,大约有10秒到20秒的突发时间,然后在100%的情况下(仅由R使用)大约90秒的一个内核,然后是其他内容的大约45秒(我保存结果并保存加载下一批数据)。 我正在批量处理40,000行,800列。
根据顶部,长期平均负载在5.00附近。
这看起来合理吗? 还是有一点R并行花费更多的时间来处理通信开销,我应该限制为例如16个内核。 这里有什么经验法则吗?
参考: CPU规格我正在使用“ Linux 4.4.5-15.26.amzn1.x86_64(amd64)”。 R版本3.2.2(2015-08-14)
更新:我尝试使用16个内核。 对于最小的数据,运行时间从13.9s增加到18.3s。 对于中型数据:
With 16 cores:
user system elapsed
30.424 0.580 60.034
With 35 cores:
user system elapsed
30.220 0.604 54.395
即, 开销部分花费了相同的时间,但是并行位的内核更少,因此花费了更长的时间,因此总体上花费了更长的时间。
我也尝试使用mclapply()
,如注释中所建议。 它的确似乎要快一些(在我尝试过的特定测试数据上大约为330s与360s),但这在我的笔记本上,在此其他过程或过热可能会影响结果。 因此,我尚未对此得出任何结论。
没有有用的经验法则-并行任务最适合的内核数量完全由所述任务确定。 有关更一般的讨论,请参见古斯塔夫森定律 。
您在代码中看到的高单核部分可能来自算法的结束阶段(“联接”阶段),在该阶段,并行结果被整理为单个数据结构。 由于这远远超出了并行计算阶段,因此这实际上可能表明较少的内核可能是有益的。
我还要补充一点,如果您不了解R中用于并行计算的出色资源,您可能会发现阅读Norman Matloff的最新著作Parallel Computing for Data Science: With Examples in R, C++ and CUDA
的Parallel Computing for Data Science: With Examples in R, C++ and CUDA
非常有帮助。 我强烈推荐它(我学到了很多东西,而不是来自CS背景)。
这本书深入回答了您的问题(特别是第2章)。 这本书对导致并行程序瓶颈的开销原因进行了高层次的概述。
引用第2.1节,该节隐式部分回答了您的问题:
并行编程中存在两个主要的性能问题:
通信开销 :通常,必须在进程之间来回传输数据。 这需要时间,这可能会对性能造成很大的影响。 此外,如果所有进程都试图一次访问相同的数据,则它们之间可能会互相干扰。 当尝试访问相同的通信通道,相同的内存模块等时,它们可能会发生冲突。 这是速度上的另一个障碍。 术语“粒度”用于大致指代计算与开销之比。 大粒度或粗粒度算法涉及足够大的计算块,因此开销并不是什么大问题。 在细粒度算法中,我们确实确实需要尽可能避免开销。
^当开销很高时,针对当前问题的较少核心可以缩短总计算时间。
负载平衡 :如上一章所述,如果我们不谨慎地将工作分配给流程,则分配给某些工作的风险要大于分配给其他工作的风险。 这会损害性能,因为在运行结束时会使某些过程失去生产力,而仍有工作要做。
什么时候不使用所有内核? 从我的个人经验中可以得出一个例子,我每天在R中运行的cronjob数据在RAM中的数据量为100-200GB,其中运行多个核以处理数据块,我确实发现32个可用核中有6个可以运行比使用20-30个内核更快。 一个主要原因是子进程需要内存(在执行了一定数量的子进程之后,内存使用率很高,并且运行速度大大降低)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.