setwd("")
library(doParallel)
library(doRNG)
setwd():
library(doParallel):
foreach는 %dopar% 연산자를 사용하더라도 작업을 순차적 (직렬)으로 실행합니다.library(doRNG)
%dorng%는 %dopar%과 달리 병렬 작업에서 재현 가능한 난수 생성을 지원하므로 동일한 결과를 도출해야 하는 (병렬) 시뮬레이션 작업을 할 수 있습니다.
nCores <- min(parallel::detectCores(), 8)
options(cores = nCores)
doParallel::registerDoParallel(cores = nCores)
source(".R")
parallel::detectCores()
options(cores = nCores):
doParallel::registerDoParallel(cores = nCores)
library(doParallel) 패키지 설명에서 library(doParallel)를 로드하지 않으면 foreach 함수는 %dopar% 연산자를 사용하더라도 병렬 작업을 못한다고 설명하였습니다.
추가로 library(doParallel)를 로드하는 것만으로는 충분하지 않으며, registerDoParallel 함수를 호출하여 병렬 백엔드를 로드해야 foreach가 병렬로 작업을 실행할 수 있습니다. doParallel을 단순히 로드한다고 해서 자동으로 병렬 처리가 이루어지는 것은 아닙니다.
source(".R")
doParallel::registerDoParallel(cores = nCores): 이 방법은 R 내부에서 자동적으로 클러스터를 생성할 수 있습니다. 다만 외부 스크립트에 패키지를 로드할 일이 있을 때 잘 호환되지 않을 수 있으므로 foreach(, .packages = c())
와 같이 foreach문 안에 추가적으로 .packages = c() 패키지를 로드 해줘야 합니다. 하지만 로드 해줘야 할 패키지가 너무 많을 때 복잡할 수 있으므로 다음과 같이 클러스트를 직접 생성하는 코드로 작업하면 됩니다.
cl <- parallel::makeCluster(nCores)
doParallel::registerDoParallel(cl)
parallel::clusterEvalQ(cl, source(".R"))
stopCluster(cl)
자동으로 클러스트를 생성하는 doParallel::registerDoParallel()와의 차이점은 source(".R")함수로 외부 스크립트를 불러오고 싶을 때 parallel::clusterEvalQ(cl, source(".R")) 를 사용해야 합니다.
또한 doParallel::registerDoParallel()는 자동으로 백엔드 클러스터를 관리하므로 작업이 끝나면 클러스터가 자동으로 종료되므로 별도로 stopCluster()를 호출할 필요가 없었지만 수동으로 클러스터를 생성하였을 경우 작업 종료 시 반드시 stopCluster()를 사용하여 백엔드 클러스트를 종료하여야 합니다.
참고
Weston S, Calaway R (2015) Getting Started with doParallel and foreach. https://cran.r-project.org/web/packages/doParallel/vignettes/gettingstartedParallel.pdf
Yoshida K, Hernández-Díaz S, Solomon DH, et al. Matching weights to simultaneously compare three treatment groups: comparison to three-way matching. Epidemiology. 2017;28(3):387-395. https://github.com/kaz-yos/mw