Hyper-threading

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.

Overhead

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

comments powered by Disqus


Back to the index

Blog roll

R-bloggers, Debian Weekly
Valid XHTML 1.0 Strict [Valid RSS] Valid CSS! Emacs Muse Last modified: oktober 17, 2019