I have a netbook dating from 2009 with a single-core processor (Intel atom N270). I had no idea hyper-threading would actually decrease time needed for the processor to do calculations, but an experiment shows that to be the case.
library(doMC) registerDoMC() x <- iris[which(iris[,5] != "setosa"), c(1,5)] trials <- 10000 ptime <- system.time({ r <- foreach(icount(trials), .combine=cbind) %dopar% { ind <- sample(100, 100, replace=TRUE) result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit)) coefficients(result1) } })[3] stime <- system.time({ r <- foreach(icount(trials), .combine=cbind) %do% { ind <- sample(100, 100, replace=TRUE) result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit)) coefficients(result1) } })[3] 100*(stime-ptime)/stime elapsed 30.93177
This means that the total time needed was reduced with 30.9 percent when hyper-threading was used compared to when hyper-threading was not used.
On a genuine dual-core processor, Intel(R) Core(TM)2 Duo CPU E8400 @ 3.00GHz, the time saved was higher, 45 percent. But 30 percent also makes the effort of parallelizing worthwile.
Before I start optimising programs using explicit parallelism, I surely would like to know about the time required to instantiate a new thread. It is - of course - only sane to optimise parts that take longer than this time to evaluate.
A simple test to measure the startup-time is the following code:
library(doMC) my.func <- function(n){ replicate(1 + 1, n = n) return(replicate(1 + 1, n = n)) } my.func.par <- function(n){ replicate(1 + 1, n = n) parallel(replicate(1 + 1, n = n)) return(collect()) } system.time(foo <- my.func(n = 1000)) system.time(foo.parallel <- my.func.par(n = 1000)) str(foo) str(foo.parallel)
On my Intel atom N270, the results was:
> system.time(foo <- my.func(n = 1000)) user system elapsed 0.016 0.000 0.017 > system.time(foo.parallel <- my.func.par(n = 1000)) user system elapsed 0.012 0.004 0.025
The time spent on starting a second thread seems to be 0.025-0.017 = 0.008 seconds.
On another box, the Intel(R) Core(TM)2 Duo CPU E8400 @ 3.00GHz, I got the following figures:
> system.time(foo <- my.func(n = 1000)) user system elapsed 0.000 0.000 0.003 > system.time(foo.parallel <- my.func.par(n = 1000)) user system elapsed 0.004 0.004 0.008
That is, 0.005 seconds to start the thread.
Suggested reading: http://www.futurechips.org/tips-for-power-coders/parallel-programming.html