# # ### Simple example of parallel processing. # # The example below simply illustrates how to use multiple cores on a # a desktop computer -- to increase the speed of time consuming # iterated analysis. # # An article offering more explanation can be found here: # http://www.unt.edu/rss/class/Jon/Benchmarks/Parallel_L_JDS_Mar2014.pdf # # First, write a 'slow' function: keep in mind, we are intentionally # making this slow so that we can show an improvement from the use # of parallel processing (i.e. using multiple cores rather than a # single processor which is the default). lockpick.fun <- function(combination, choices){ ch <- seq(1:choices) solution.matrix <- expand.grid(ch, ch, ch) i <- 0 picked <- "FALSE" while(picked == "FALSE"){ i <- i + 1 draw <- solution.matrix[i,] if(combination[1] == draw[1] & combination[2] == draw[2] & combination[3] == draw[3]){ picked <- "TRUE"; print("PICKED!!")} } out <- paste("Number of iterations =", i, sep = " ") return(out) } # Next, set the number of possible values for each of the lock's combination # spaces. choi <- 50; choi # Next, randomly draw a combination -- which 'opens' the lock. combin <- sample(seq(1:choi), 3, replace = T); combin # Next, apply the function from above to find our combination # using 'brute force'. system.time(test.1 <- lockpick.fun(combination = combin, choices = choi)) test.1 rm(test.1) # Comparison Test: library(doParallel) # Next, register two cores -- obviously more cores can be registered if # the machine has more than two cores; however, it may be important to # leave one core not registered so that the user can continue to do # other tasks while R is processing an analysis. registerDoParallel(cores = 2) # For the comparison, we're going to run the same application (lockpick) as # we did above, but we're going to run it three times for each of # two tests -- the first test (baseline = b) using a simple for-loop and # the second test (test = t) using the foreach multi-core method. # First, run the baseline for comparision (without using multiple cores). b.results <- as.list(0) b.time <- system.time(for (i in 1:3){ b.results[[i]] <- lockpick.fun(combination = combin, choices = choi) })[3] b.results b.time # Next, run the testing function(s). t.time <- system.time(t.results <- foreach(i = 1:3) %dopar% lockpick.fun(combination = combin, choices = choi))[3] t.results t.time # To estimate the percentage decrease in time elapsed.... (b.time - t.time)/b.time # A second way of doing the baseline version....using only one core. s.time <- system.time(s.results <- foreach(i = 1:3) %do% lockpick.fun(combination = combin, choices = choi))[3] s.results s.time # Notice below, the 's.time' and 'b.time' are virtually identical. combin b.time s.time t.time # Finally, clean up the workspace. rm(b.results, b.time, choi, combin, i, lockpick.fun, s.results, s.time, t.results, t.time) detach("package:doParallel") detach("package:foreach") detach("package:iterators") detach("package:parallel") # # References & Resources: # # Eddelbuettel, D. (2013). CRAN Task View: High-Performance and Parallel Computing with R. Available at: http://cran.r-project.org/web/views/HighPerformanceComputing.html # # Hornik, K. (2014). R FAQ (section 5.1.1 R Add-On Packages): List of packages which are included with a the R distribution. Available at: http://cran.r-project.org/faqs.html # # Brian Ripley, Luke Tierney and Simon Urbanek. (2014). Package parallel. Manual available at: http://stat.ethz.ch/R-manual/R-devel/library/parallel/doc/parallel.pdf # # Weston, S., [Revolution Analytics]. (2014). Package doParallel. Documentation available at CRAN: http://cran.r-project.org/web/packages/doParallel/index.html # # Weston, S., [Revolution Analytics]. (2013). Package foreach. Documentation available at CRAN: http://cran.r-project.org/web/packages/foreach/index.html # End script.