5

長い間、私は多くの並列 r スクリプトに sfLapply を使用してきました。しかし、最近は並列コンピューティングについて詳しく調べているので、sfClusterApplyLB を使用しています。これにより、個々のインスタンスの実行に同じ時間がかからない場合に、多くの時間を節約できます。sfLapply が新しいバッチをロードする前にバッチの各インスタンスが終了するのを待つ場合 (アイドル状態のインスタンスにつながる可能性があります)、タスクを完了した sfClusterApplyLB インスタンスはすぐにリスト内の残りの要素に割り当てられるため、かなり節約できる可能性がありますインスタンスが正確に同じ時間がかからない時間の。これにより、降雪を使用するときに実行の負荷を分散させたくないのはなぜでしょうか? これまでに見つけた唯一のことは、並列スクリプトにエラーがある場合、sfClusterApplyLB はエラーが発生する前にリスト全体を循環しますが、sfLapply は最初のバッチを試行した後に停止します。他に何が欠けていますか?負荷分散のその他のコスト/欠点はありますか? 以下は、2 つの違いを示すコード例です。

rm(list = ls()) #remove all past worksheet variables
working_dir="D:/temp/"
setwd(working_dir)
n_spp=16
spp_nmS=paste0("sp_",c(1:n_spp))
spp_nm=spp_nmS[1]
sp_parallel_run=function(sp_nm){
  sink(file(paste0(working_dir,sp_nm,"_log.txt"), open="wt"))#######NEW
  cat('\n', 'Started on ', date(), '\n') 
  ptm0 <- proc.time()
  jnk=round(runif(1)*8000000) #this is just a redundant script that takes an arbitrary amount of time to run
  jnk1=runif(jnk)
  for (i in 1:length(jnk1)){
    jnk1[i]=jnk[i]*runif(1)
  }
  ptm1=proc.time() - ptm0
  jnk=as.numeric(ptm1[3])
  cat('\n','It took ', jnk, "seconds to model", sp_nm)

  #stop sinks
  sink.reset <- function(){
    for(i in seq_len(sink.number())){
      sink(NULL)
    }
  }
  sink.reset()
}
require(snowfall)
cpucores=as.integer(Sys.getenv('NUMBER_OF_PROCESSORS'))

sfInit( parallel=T, cpus=cpucores) # 
sfExportAll() 
system.time((sfLapply(spp_nmS,fun=sp_parallel_run)))
sfRemoveAll()
sfStop()

sfInit( parallel=T, cpus=cpucores) # 
sfExportAll() 
system.time(sfClusterApplyLB(spp_nmS,fun=sp_parallel_run)) 
sfRemoveAll()
sfStop()
4

1 に答える 1