R 多线程
来源:互联网 发布:淘宝的国行jbl靠谱吗 编辑:程序博客网 时间:2024/05/21 08:42
R 语言多线程
- parallel包
- parLapply简单的代码实战
- foreach包
- foreach简单的代码实战
目录
- R 语言多线程
- 目录
- parallel包
- 包的安装
- 包中常用函数
- parLapply的简单代码实战
- 检查当前核数
- 启动集群和关闭集群
- parLapply执行多线程计算
- 时间开销对比
- 上一级环境中变量的引入
- foreach包
- 包的安装
- foreach的使用
- 上一级环境中变量的引入
parallel包
包的安装
install.packages("parallel")library(parallel)
包中常用函数
- detectCores()
检查当前的可用核数
- clusterExport()
配置当前环境
- makeCluster()
分配核数
- stopCluster()
关闭集群
- parLapply()
lapply()函数的并行版本
其实R语言本来就是一门向量化语言,如果是对于一个向量的操作,使用apply函数一族能获得比较高的效率,相比于for循环,这种高效来自于:
- 用C实现了for循环
- 减少对于data.frame等数据结构等不必要的拷贝
但是很多时候,如果想更快的话,光apply函数一族还不足够,这时候就能用上多线程。
R语言parallel包可以帮助实现多线程。
parLapply的简单代码实战
检查当前核数
cl.cores <- detectCores()#结果> cl.cores[1] 8
启动集群和关闭集群
cl <- makeCluster(4) # 初始化四核心集群###并行任务stopCluster(cl) # 关闭集群
parLapply执行多线程计算
#定义计算平方函数square <- function(x){ return(x^2)}
#利用并行计算计算平方函数num <- c(1:3)cl <- makeCluster(4) # 初始化四核心集群results <- parLapply(cl,num,square)#调用parLapply并行计算平方函数final <- do.call('c',results)#整合结果stopCluster(cl) # 关闭集群#结果> final[1] 1,4,9
思考:在如此小的计算方式下,开4个核计算是否比开一个核要快
答案:当然是不一定,因为涉及到调度方式等额外开销,所以不一定快,因为真正并行起作用的地方在于大数据量的计算。
时间开销对比
两段对比代码
#定义计算平方函数square <- function(x){ ######### #一段冗余代码增加执行时间 y = 2*x if(y <300) {z = y} else {z = x} ########## return(x^2)}num <- c(1:10000000)
#并行计算print(system.time({ cl <- makeCluster(4) # 初始化四核心集群 results <- parLapply(cl,num,square)#调用parLapply并行计算平方函数final <- do.call('c',results)#整合结果stopCluster(cl) # 关闭集群}))#结果用户 系统 流逝 7.89 0.27 19.01
#普通计算print(system.time({ results <- lapply(num,square) final <- do.call('c',results)#整合结果}))#结果用户 系统 流逝 29.74 0.00 29.79
显然在数据量比较大的时候,并行计算的时间几乎就是于核数反比。不过,也不是多开几个核就好,注意内存很容易超支的,每个核都分配相应的内存,所以要注意内存开销。出现内存问题的时候,需要检查是否代码是否合理,R语言版本(64位会比32位分配的内存大),核分配是否合理。
上一级环境中变量的引入
R语言里边对于环境变量有着有趣的定义,一层套一层,这里不做深入展开。
类似于在c语言函数中使用全局变量,R在执行并行计算的时候,如果需要计算的函数出现在全局(上一级),那么就需要声明引入这个变量,否则将会报错。
#定义计算幂函数base = 2square <- function(x){ return(x^base)}num <- c(1:1000000)
#利用并行计算计算幂函数cl <- makeCluster(4) # 初始化四核心集群results <- parLapply(cl,num,square)#调用parLapply并行计算平方函数final <- do.call('c',results)#整合结果stopCluster(cl) # 关闭集群#结果报错Error in checkForRemoteErrors(val) : 4 nodes produced errors; first error: 找不到对象'base'
#利用并行计算计算幂函数cl <- makeCluster(4) # 初始化四核心集群clusterExport(cl,"base",envir = environment())results <- parLapply(cl,num,square)#调用parLapply并行计算平方函数final <- do.call('c',results)#整合结果stopCluster(cl) # 关闭集群#结果> final[1] 1,4,9,16,25.......
foreach包
除了parallel包以外,还有针对并行for循环的foreach包,foreach()的使用也与parLapply()类似,两个功能也类似,其中遇到的问题也类似。
包的安装
install.packages("foreach")library(parallel)
foreach的使用
#定义计算幂函数square <- function(x){ return(x^2)}
非并行情况的使用:
参数中的combine就是整合结果的函数,可以是c,可以是rbind,也可以是+等
results = foreach(x = c(1:3),.combine = 'c') %do% square(x)#结果> results[1] 1,4,9
并行情况的使用:
注意并行情况的时候,需要与parallel包进行配合,引入library(doParallel)。同时%do%需要改成%dopar%。另外与parallel包不一样的是,需要多加一句registerDoParallel(cl)来注册核进行使用。
cl <- makeCluster(4)registerDoParallel(cl)results = foreach(x = c(1:100000),.combine = 'c') %dopar% square(x)stopCluster(cl)
上一级环境中变量的引入
同parallel包并行计算前需要clusterExport()来引入全局变量一样,foreach也同样需要声明,不同的是,foreach声明方式直接写在foreach()的参数export里边。
#定义计算幂函数base = 2square <- function(x){ return(x^base)}cl <- makeCluster(4)registerDoParallel(cl)results = foreach(x = c(1:100000),.combine = 'c',.export ='base' ) %dopar% square(x)stopCluster(cl)
- R 多线程
- Java多线程讨论 (r)
- Java 多线程实现死锁场景 (r)
- Java 多线程 join和interrupt 方法 (r)
- JAVA多线程程序设计23个要点 (r)
- Java多线程系列--“基础篇”01之 基本概念 (r)
- Java多线程系列--“基础篇”04之 synchronized关键字 (r)
- Java多线程系列--“基础篇”06之 线程让步 (r)
- Java多线程系列--“基础篇”07之 线程休眠 (r)
- Java多线程系列--“基础篇”08之 join() (r)
- Java多线程系列--“JUC原子类”01之 框架 (r)
- Java多线程系列--“JUC锁”01之 框架 (r)
- Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock (r)
- Java多线程系列--“JUC锁”06之 Condition条件 (r)
- Java多线程系列--“JUC锁”07之 LockSupport (r)
- 40个Java多线程问题总结 (r)
- Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock (r)
- R语言多线程运算(解决R循环慢的问题)
- 关于Tomcat7启动闪退的解决办法
- 快速排序算法及JAVA实现
- shell基本命令
- TCP/IP分层模型
- 使用ajax与js查询后台数据
- R 多线程
- 微信服务器配置验证失败
- 统计学习(监督学习)框架总结
- RPGMaker MV 插件基础02:插件的参数定义
- Lua中点号与冒号的区别
- SpringBoot(三):springboot整合mybatis(xml形式)
- 【10% free time】Tomcat学习之一:下载源码,导入eclipse
- HDU 1047Integer Inquiry(简单大数)
- java.util.concurrent介绍