R에서의 연산속도를 향상시키기 위해, Parallel 연산과 Rcpp를 고려하게 될 것이다.
이 포스팅에선 Rcpp::function은 이미 다 짠 상태인데 Parallel 연산 안에서 어떻게 Rcpp를 다룰지에 대해 이야기하겠다.
여기서 이야기하는 R에서의 Parallel 연산이란,
Parallel 연산을 도와주는 패키지를 사용하여 main session 이 아닌 추가적인 session 을 생성하고 각 session 에서 작동시킨 결과를 다시 main session 에서 통합시켜서 계산하는 방법을 의미한다.
이 때 한 명이 4개의 일을 처리하는게 아닌, 4명이 일을 1개씩 처리하기 때문에 계산속도가 빨라진다.
(단, 일을 전달하고 각 일의 결과를 받는 과정 또한 시간이 걸릴 수 있음)
문제는 각각의 Session 들이 중간 과정에서 생성된 변수들을 공유하지 않기 때문에, 각각의 Session에서 모든 변수를 추가로 정의해주어야 한다.
Rcpp 함수 또한 각 Session 마다 실행시켜주어야 하는데,
(1) 각 session 마다 Rcpp 파일을 불러오거나 (이 때 library를 통해 직접 Rcpp 패키지를 로딩해야 에러가 발생하지 않는다.),
(2) 각 session 마다 Rcpp 함수를 직접 정의해야 한다.
(1) 세션마다 .cpp 파일 불러오기
(1-1) foreach 사용시 { } 안에 사용하고자 하는 함수를 불러오는 코드를 함께 작성한다.
# Parallel Session 생성
num_cl <- 10
registerDoParallel(cl <- makeCluster(num_cl))
final_list <- foreach(i=1:10) %dopar% {
library(RcppArmadillo);
library(Rcpp);
library(RcppEigen);
Rcpp::sourceCpp("user_defined_function.cpp")
}
stopCluster(cl)
(1-2) parLapply 사용시 (1-1)처럼 모든 반복마다 불러오게끔 작성해도 되고, clusterEvalQ()를 사용하여 미리 정의할 수도 있다.
cl <- makeCluster(num_cl)
clusterExport(cl, varlist= c("nn", "p",
"K", "lambda", "tr_beta"))
clusterEvalQ(cl, {
library(RcppArmadillo);
library(Rcpp);
library(RcppEigen);
Rcpp::sourceCpp("user_defined_function.cpp")})
la_results <- parLapply(cl, 1:R, function(r) {
## user_defined_function.cpp 에서 정의된 function을 사용하는 코드 작성 ##
})
stopCluster(cl)
(2) 직접 정의
sourceCpp( )과 cppFunction 을 (1-2) 처럼 사용해도 된다.
단, code 가 너무 긴 경우 (1)이 편할 것이고 짧은 경우 (2)가 편한데, rcpp_code 또한 각 session 마다 정의되어야 하기 때문에 sourceCpp() 이나 cppFunction() 안에서 직접 정의하는 방법도 있다.
rcpp_code <-
"
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double user_defined( ) {
### fill ###
}
}"
# we can defined rcpp_code as follows:
sourceCpp(code = rcpp_code);
cppFunction(rcpp_code);
'R Programming > Rcpp' 카테고리의 다른 글
Rcpp에서 R내장 함수를 불러와서 써도 빠를까? (1) | 2024.01.08 |
---|---|
[Rcpp] building shared library 문제 해결: 환경변수 추가 (0) | 2023.10.26 |
[Rcpp] Rcpp에서 R함수 사용하기 (Optimize 함수 예시) (0) | 2023.09.17 |