더북(TheBook)

foreach()와 %dopar%를 사용한 병렬화

foreach( )에서 %do%를 사용해 순차적으로 각 폴드를 처리하는 코드의 수행 시간은 다음과 같이 system.time( )을 사용해 측정할 수 있다.

> system.time(ctree_result <- foreach(f=folds) %do% {
+   model_ctree <- ctree(
+     survived ~ pclass + sex + age + sibsp + parch + fare + embarked,
+     data=f$train)
+   predicted <- predict(model_ctree, newdata=f$validation,
+                        type="response")
+   return(list(actual=f$validation$survived, predicted=predicted))
+ })
  user system elapsed
 3.132  0.000   3.145

doMC 또는 doParallel 패키지를 사용해 4개의 작업을 동시에 실행하도록 하기 위해 registerDoMC(cores=4)를 수행한 뒤 %do% 대신 %dopar%를 지정하면 4개 폴드를 동시에 처리하는 병렬 처리가 가능하다.

> library(doMC)
> # doParallel을 사용하는 경우 registerDoParallel()을 호출한다.
> registerDoMC(cores=4)
> system.time(ctree_result <- foreach(f=folds) %dopar% {
+   model_ctree <- ctree(
+     survived ~ pclass + sex + age + sibsp + parch + fare + embarked,
+     data=f$train)
+   predicted <- predict(model_ctree, newdata=f$validation,
+                        type="response")
+   return(list(actual=f$validation$survived, predicted=predicted))
+ })
  user system elapsed
 3.804  0.108   1.032

병렬 처리를 사용하면 수행 성능은 빨라지지만 다음 사항에 주의해야 한다.

CPU 코어 개수를 고려해 동시에 수행할 작업의 개수를 설정해야 한다. 특히 입출력이 적고 CPU 연산이 많은 대부분의 기계 학습 함수의 경우 CPU 코어 개수보다 너무 많은 작업을 동시에 실행하면 성능이 오히려 떨어질 수 있다. 예를 들어, 코어가 4개인 머신에서 registerDoMC(cores=16)을 지정하면 registerDoMC(cores=8)보다 느리게 수행될 수 있다.

메모리 사용량에 따라 동시 작업의 수를 조절해야 한다. 기계 학습 알고리즘의 수행에는 때때로 많은 메모리가 필요하며, 동시에 수행되는 작업의 수에 비례해 메모리 사용량이 늘어난다. R 코드가 필요로 하는 메모리의 양이 시스템에 장착된 물리적 메모리를 초과하게 되면 디스크를 메모리로 사용하기 시작하게 된다. 그러면 메모리와 디스크 사이의 데이터 이동에만 긴 시간을 허비할 수 있고 이에 따라 코드 수행의 전체 시간이 길어질 수 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.