并行化你的运算-初识parallel包
当前位置:以往代写 > 其他教程 >并行化你的运算-初识parallel包
2019-06-14

并行化你的运算-初识parallel包

并行化你的运算-初识parallel包

R 2.14.0版本今后,parallel包被作为焦点包引入R,这个包主要成立在 multicore 和 snow 包的事情基本之上,包括了这两个包大部门成果函数,以及集成了随机数产生器。

实际上对付R来说,并行化可以在差异的层级上实现:好比,在最底层,此刻的多核CPU可以实现一些基本的数值运算(好比整数和浮点算数);高级一点的,一些扩展BLAS包利用多线程并行处理惩罚向量和矩阵的操纵,甚至有些R扩展包,通过挪用OpenMP(注释1)或pthreads来利用C 级此外多线程方法。

本文的主角,parallel包却是从别的角度的实现,简朴说是一种“粗粒度”的并行化方法。在我们的日常事情中会碰着一下环境:

  • 在差异的数据集上应用沟通的R函数

  • bootstrap计较

  • 对付第一种环境,一般会回收显式轮回或隐式轮回的方法,但惋惜的是R并不能识别这是并行计较,依旧凭据串行的方法举办处理惩罚。第二种环境,如蒙特卡洛模仿,但在同一个R历程中,所有的运算都是按顺序举办的,能做的就是多开几个R,将各个运算人工分派,最后手工归并功效,囧


    我们再仔细思量一下第一种环境(第二种环境也雷同),要害在于这些计较并不关联,可能说不需要举办通讯。这样的计较进程可以利用如下方法来表述:


    1. 启动M个隶属历程,并初始化

    2. 针对付任务,为每个隶属历程分发所有的数据

    3. 将任务大致的分为M个块儿(chunks),并将这些块儿发送到隶属历程(包括需要的R代码)

    4. 期待所有的隶属历程完成计较任务,并返回功效

    5. 对付其他任务也同样反复2-4

    6. 封锁隶属历程

    对付上述的并行化方法,隶属历程可以利用如下方法构建:

  • 通过system(“Rscript”)或雷同方法,道理即在同一台或雷同的呆板上开启一个完全沟通的R安装措施,尔后在主、副历程间通过sockets通讯。这种方法在所有的R平台上都可以利用,snow包就实现了这种方法。

  • 通过forking。Fork是可移植操纵系统(POSIX operating system)上的观念,这种方法合用于除Windows以外的所有平台。它的做法是建设一个新的完全拷贝主历程的副历程,包罗workspace以及其他状态(如随机数流)。这种拷贝方法在内存页面产生变革前是共享内存的,因此速度很快。但这种方法也有缺点,它共享了整个历程,甚至包罗GUI元素。这大概会导致一些bug。multicore包则实现了这种方法。

  • 虽然,对付这两种并行化方法,的R自带的parallel包都有支持。尚有一种是通过OS级的通讯方法,好比PVM (`parallel virtual machine’),以及SGE等,同样有相关的技能和包来支持,这里不再展开接头。

    我们此刻说一些实际的,如安在实际项目应用中利用并行化计较方法来提高我们的事情效率。在parallel包里,对应上述两种并行化方法有如下两个焦点函数(针对付lapply函数的并行化,mclapply在windows上不能利用):

  • parLapply(cl, x, FUN, …)

  • mclapply(X, FUN, …, mc.cores)

  • 思量 lapply这个函数,这种隐式轮回函数,它实际就是对差异的数据应用了沟通的函数,是可以并行化的。首先看一个例子:
    doit <- function(x)(x)^2 + 2*x
    system.time(res <- lapply(1:5000000, doit))
    user system elapsed
    24.05 0.05 24.20

    上述lapply的表达同一个for轮回没什么两样,但由于数据集较量大,500w,所以耗损的时间相对较长。我们利用parallel包来加快:

    library(parallel)
    cl <- makeCluster(getOption(“cl.cores”, 3)) # use 3 cores
    system.time(res <- parLapply(cl, 1:5000000, doit))
    user system elapsed
    6.54 0.34 19.95
    stopCluster(cl) # close clusters

    运行parLapply的时候,处理惩罚器三个焦点瞬间占满,很快就将功效返回。不外这个函数有两点要留意:



    1. 首先要先用detectCores函数确定系统焦点数目,对付Window系统下的Intel I5或I7 处理惩罚器,一般利用detectCores(logical = F)来得到实际的物理焦点数量。

    2. 由于这个函数利用的是挪用Rscript的方法,这个例子里,工具被复制了三份,因此内存会吃的很锋利,在大数据条件就要小心利用

    在Linux下利用mclapply函数的结果如下:
    mc <- getOption(“mc.cores”, 3)
    system.time(res <- mclapply(1:5000000, doit, mc.cores = mc))
    user system elapsed
    6.657 0.500 7.181

    除了对付lapply,sapply这类函数的并行化外,parallel包尚有针对付apply的并行化函数,好比parApply,以及种种动态均衡的函数如parLapplyLB,请拜见parallel包的辅佐文档。

    注释1:OpenMP (Open Multiprocessing) is an API that supports multi-platform shared memory multiprocessing programming in C,C++, and Fortran, on most processor architectures and operating systems.

      关键字:

    在线提交作业