在R中并行计算时改变核数

在R中并行计算时改变核数,r,parallel-processing,R,Parallel Processing,我正在使用parallel包和mclappy执行R中的并行化代码,它将预定义的内核数作为参数 如果我有一份工作要运行几天,有没有一种方法可以让我写(或包装)我的mclappy功能在服务器高峰时间使用更少的内核,在非高峰时间提高使用率?我想最简单的解决方案是将数据分割成更小的数据块,并分别在这些数据块上运行mclappy。然后,您可以为每次运行mclappy设置内核数。对于运行时方差很小的计算,这可能会更好 我已经创建了一个快速而肮脏的模型,描述了它的样子: library(parallel) l

我正在使用
parallel
包和
mclappy
执行R中的并行化代码,它将预定义的内核数作为参数


如果我有一份工作要运行几天,有没有一种方法可以让我写(或包装)我的
mclappy
功能在服务器高峰时间使用更少的内核,在非高峰时间提高使用率?

我想最简单的解决方案是将数据分割成更小的数据块,并分别在这些数据块上运行
mclappy
。然后,您可以为每次运行
mclappy
设置内核数。对于运行时方差很小的计算,这可能会更好

我已经创建了一个快速而肮脏的模型,描述了它的样子:

library(parallel)
library(lubridate)

#you would have to come up with your own function
#for the number of cores to be used
determine_cores=function(hh) {
  #hh will be the hour of the day
  if (hh>17|hh<9) {
    return(4)
  } else {
    return(2)
  }
}

#prepare some sample data
set.seed(1234)
myData=lapply(seq(1e-1,1,1e-1),function(x) rnorm(1e7,0,x))

#calculate SD with mclapply WITHOUT splitting of data into chunks
#we need this for comparison
compRes=mclapply(myData,function(x) sd(x),mc.cores=4)

set.seed(1234)
#this will hold the results of the separate mclapply calls
res=list()
#starting position within myData
chunk_start_pos=1
calc_flag=TRUE

while(calc_flag) {
  #use the function defined above to determine how many cores we may use
  core_num=determine_cores(lubridate::hour(Sys.time()))
  #determine end position of data chunk
  chunk_end_pos=chunk_start_pos+core_num-1
  if (chunk_end_pos>=length(myData)) {
    chunk_end_pos=length(myData)
    calc_flag=FALSE
  }
  message("Calculating elements ",chunk_start_pos," to ",chunk_end_pos)
  #mclapply call on data chunk
  #store data in res
  res[[length(res)+1]]=mclapply(myData[chunk_start_pos:(chunk_start_pos+core_num-1)],
                                function(x) sd(x),
                                mc.preschedule=FALSE,
                                mc.cores=core_num)
  #calculate new start position
  chunk_start_pos=chunk_start_pos+core_num
}

#let's compare the results
all.equal(compRes,unlist(res,recursive=FALSE))
#TRUE
库(并行)
图书馆(lubridate)
#你必须想出你自己的功能
#要使用的芯数
确定核心=功能(hh){
#hh将是一天中最重要的时刻
如果(hh>17 | hh=长度(myData)){
chunk\u end\u pos=长度(myData)
calc_标志=错误
}
消息(“计算元素”,块开始位置,“到”,块结束位置)
#数据块上的mclapply调用
#将数据存储在res中
res[[length(res)+1]=mclapply(myData[chunk\u start\u pos:[chunk\u start\u pos+core\u num-1]),
功能(x)sd(x),
mc.preschedule=FALSE,
mc.cores=core_num)
#计算新的起始位置
chunk\u start\u pos=chunk\u start\u pos+核心数量
}
#让我们比较一下结果
all.equal(压缩,未列出(res,递归=FALSE))
#真的

我想您必须为McLappy添加一个层。基本上是将作业列表分批进行。每批将由MCLAPPY执行。在运行新批处理之前,您可以查看服务器状态,然后决定运行下一批处理的适当内核数。@KarlForner是的,我也会这样做。