R语言常用两种并行方法之snowfall详解

上一篇博客(R中两种常用并行方法之parallel)中已经介绍了R中常见的一种并行包:parallel,其有着简单便捷等优势,其实缺点也是非常明显,就是很不稳定。很多时候我们将大量的计算任务挂到服务器上进行运行时,更看重的是其稳定性。

这时就要介绍R中的另一个并行利器——snowfall,这也是在平时做模拟时用的最多的一种方法。

针对上篇中的简单例子

首先是一个最简单的并行的例子,这个例子不需要载入任何依赖库、函数、对象等。相对也比较简单:

library(snowfall)  # 载入snowfall包

# 并行初始化
sfInit(parallel = TRUE, cpus = detectCores() - 1)

# 进行lapply的并行操作
sfLapply(1:3, function(x) c(x, x ^ 2, x ^ 3))

# 结束并行,返还内存等资源
sfStop()

语法基本也比较好理解,代码中的注释也有进行说明。sfLapply()的操作是与lapply()相对应的。类似地,还有sfSapply()sfApply()等函数,其用法与apply组中的函数一致。

snowfall进阶

在实际操作时,我们进行的函数往往没有这么简单,往往还需要依赖一些其它的函数、变量、R包等,这时就不能用上述的方法简单的进行操作了。

下面给出一个具体实际的操作案例,来展示如何载入函数中依赖的对象等参数。

n <- 100
m <- 100

fun1 <- function(...) {
  ...
}

fun2 <- function(...) {
  ...
}

sfInit(parallel = TRUE, cpus = 10) #初始化

sfLibrary(MASS)     # 载入依赖R包MASS
sfLibrary(ggplot2)  # 载入依赖R包ggplot2

sfExport("n", "m")         # 载入依赖的对象
sfExport("fun1", "fun2")   # 载入依赖的函数

# 并行计算
result <- sfLapply(1:10000, myfun)
# 注意:myfun是自己定义的函数,里面需要用到包MASS, ggplot2;变量m, n;函数fun1, fun2。

sfStop() # 结束并行

其实很简单,对于并行函数依赖的库,就是sfLibrary()进行载入,所以来的对象以及函数则使用sfExport()进行载入。

当函数或者对象非常多时,不方便一个一个单独输入,这时我们可将所有的对象与函数存到allfun.R文件夹中,然后再采用sfSource('allfun.R')将所有的对象与函数进行导入,方便快捷。

下面我们再来看看如何查看并行进度:

使用sfCat查看并行进度

这部分参考:How to output a message in snowfall?

我们只需在函数中添加sfCat()函数,即可查看并行进度,其示例代码如下所示:

sfInit(parallel = TRUE, cpus = 2, slaveOutfile = "test.txt")
sfLibrary(snowfall)

res <- sfLapply(1:100, function(x) {
  sfCat(paste("Iteration ", x), sep = "\n")
})

sfStop()

需要注意的是,在初始化并行中,我们多加了一串命令:slaveOutfile = "test.txt",这个表示其显示的进度会储存在test.txt文件中,其余部分基本没什么变化。

与Rcpp结合会遇到的问题

当我们进行模拟想要再次进行提速时,通常都会使用Rcpp将我们的R代码改成C++代码。平时在我们使用的时候,直接使用Rcpp::sourceCpp()就可以直接将我们的C++代码中的函数进行导入,然想要使用snowfall进行并行时则会遇到问题。

这里使用了两种方法来进行尝试:

使用sfSource('myCppfun.cpp')进行导入,会在导入的时候直接报错。

先使用Rcpp::sourceCpp('myCppfun.cpp')将函数读入变量空间,然后再使用sfExport("myCppfun")将函数。这样做在最后运行代码的时候会报错。

所以遇到这种问题,只能将我们的C++代码中的函数打包成一个包,然后直接在使用snowfall进行并行时,调取这个包来运行则不会报错。

关于如何制作自己的R包,可参考:RStudio制作包含Rcpp代码的R包。

以上就是R语言常用两种并行方法之snowfall详解的详细内容,更多关于R语言并行snowfall方法的资料请关注我们其它相关文章!

(0)

相关推荐

  • R语言通过parallel包实现多线程运行方式

    总的来说,R的运算速度不算快,不过类似并行运算之类的改进可以提高运算的性能.下面非常简要地介绍如何利用R语言进行并行运算 library(parallel) cl.cores <- detectCores() cl <- makeCluster(cl.cores) detectCores( )检查当前电脑可用核数. makeCluster(cl.cores)使用刚才检测的核并行运算.R-Doc里这样描述makeCluster函数:Creates a set of copies of R run

  • R语言常用两种并行方法之parallel详解

    目录 并行计算 在模拟时什么地方可以用到并行? 怎么在R中看我们可以使用并行? parallel(简单) 由于最近在进行一些论文的模拟,所以尝试了两种并行的方法:parallel与snowfall,这两种方法各有优缺,但还是推荐snowfall,整体较为稳定,不容易因为内存不足或者并行线程过多等原因而报错. 并行计算 并行计算: 简单来讲,就是同时使用多个计算资源来解决一个计算问题,是提高计算机系统计算速度和处理能力的一种有效手段.(参考:并行计算简介) 一个问题被分解成为一系列可以并发执行的离

  • R语言中for循环的并行处理方式

    前言 本文用于记录笔者在将R语言中的for语句并行化处理中的一些问题. 实验 这里使用foreach和doParallel包提供的函数实现for语句的并行处理. for语句脚本 func <- function(x, y, z) { return(x^y/z) } # >>> main <<< x <- 2 y <- 3 z <- 1:100000 start <- (proc.time())[3][[1]] a <- 0 for (

  • R语言常用两种并行方法之snowfall详解

    上一篇博客(R中两种常用并行方法之parallel)中已经介绍了R中常见的一种并行包:parallel,其有着简单便捷等优势,其实缺点也是非常明显,就是很不稳定.很多时候我们将大量的计算任务挂到服务器上进行运行时,更看重的是其稳定性. 这时就要介绍R中的另一个并行利器--snowfall,这也是在平时做模拟时用的最多的一种方法. 针对上篇中的简单例子 首先是一个最简单的并行的例子,这个例子不需要载入任何依赖库.函数.对象等.相对也比较简单: library(snowfall) # 载入snowf

  • R语言刷题检验数据缺失类型过程详解

    目录 题目 解答 下面考虑三种情况: 1. a = 0, b = 0 2. a = 2, b = 0 3. a = 0, b = 2 题目 解答 由于题目要求需要重复三次类似的操作,故首先载入所需要的包,构造生成数据的函数以及绘图的函数: library(tidyr) # 绘图所需 library(ggplot2) # 绘图所需 # 生成数据 GenerateData <- function(a = 0, b = 0, seed = 2018) { set.seed(seed) z1 <- r

  • C语言常用库函数的使用及模拟实现详解例举

    目录 1.strlen 1.计数法 2.递归法 3.指针减指针 2.strcpy 3.strcmp 4.strcat 5.strstr 6.strtok 7.字符分类函数 8.memcpy&memmove 9.memcmp 经历了C语言基础篇的学习,让我们来简单了解几个C语言的库函数! 1.strlen 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' ). 函数的模拟实现 1.计数法 int my_strlen(dest)

  • R语言使用cgdsr包获取TCGA数据示例详解

    目录 TCGA数据源 TCGA数据库探索工具 查看任意数据集的样本列表方式 选定数据形式及样本列表后获取感兴趣基因的信息,下载mRNA数据 选定样本列表获取临床信息 综合性获取 下载mRNA数据 获取病例列表的临床数据 从cBioPortal下载点突变信息 从cBioPortal下载拷贝数变异数据 把拷贝数及点突变信息结合画热图 TCGA数据源 众所周知,TCGA数据库是目前最综合全面的癌症病人相关组学数据库,包括的测序数据有: DNA Sequencing miRNA Sequencing P

  • Java 两种延时thread和timer详解及实例代码

    Java 两种延时thread和timer详解及实例代码 在Java中有时候需要使程序暂停一点时间,称为延时.普通延时用Thread.sleep(int)方法,这很简单.它将当前线程挂起指定的毫秒数.如 try { Thread.currentThread().sleep(1000);//毫秒 } catch(Exception e){} 在这里需要解释一下线程沉睡的时间.sleep()方法并不能够让程序"严格"的沉睡指定的时间.例如当使用5000作为sleep()方法的参数时,线 程

  • Android 两种启动模式的实例详解

    Android 两种启动模式的实例详解 Intent的FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_REORDER_TO_FRONT Activity的两种启动模式:FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_REORDER_TO_FRONT 1. 如果已经启动了四个Activity:A,B,C和D.在D Activity里,我们要跳到B Activity,同时希望C finish掉,可以在startActivity(intent)里

  • 对Python中创建进程的两种方式以及进程池详解

    在Python中创建进程有两种方式,第一种是: from multiprocessing import Process import time def test(): while True: print('---test---') time.sleep(1) if __name__ == '__main__': p=Process(target=test) p.start() while True: print('---main---') time.sleep(1) 上面这段代码是在window

  • Vue中Router路由两种模式hash与history详解

    hash 模式 (默认) 工作原理: 监听网页的hash值变化 -> onhashchange事件, 获取location.hash 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载. 会给用户好像跳转了网页一样的感觉, 但是实际上没有跳转 主要用在单页面应用(SPA) // 模拟原理 // 监听页面hash值变化 window.onhashchange = function(){ // 获取当前url的哈希值 const _hash = locat

  • Spring依赖注入的两种方式(根据实例详解)

    1,Set注入    2,构造注入 Set方法注入: 原理:通过类的setter方法完成依赖关系的设置 name属性的取值依setter方法名而定,要求这个类里面这个对应的属性必须有setter方法. Set方法注入时spring中配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans&qu

随机推荐