I set out to find out whether I could speed up R by compiling it from
source and:
- using Apple´s Accelerate Framework
- enabling OpenMP (which is disabled under OS X and Windows by default, but
enabled under Linux I believe)
- using Intel´s Intel´s Math Kernel Library
I also wanted to know how an implicit parallel library, like OpenMP,
performs within explicit parallelism, e.g. calls from the =parallel=
package.

So I compiled 6 different versions of R 3.01 on OS X and tested them
for speed against the OS X .pkg from CRAN. I used gcc 4.8 (not the gcc
4.2 from Apple), which you I downloaded from http://hpc.sourceforge.net/.
For MKL, I used
both the GNU (gcc, gfortran) and the Intel compilers (icc,
ifortran). The 6 versions and their =configure= settings are:

1) https://gist.github.com/ronert/5645530 R 3.01 compiled with Apple´s
Accelerate framework
2) https://gist.github.com/ronert/5645541 R 3.01 compiled with OpenMP
enabled
3) https://gist.github.com/ronert/5645561 R 3.01 compiled with gcc and
gfortran using Intel MKL (sequential)
4) https://gist.github.com/ronert/5645576R 3.01 compiled with icc and
ifortran using Intel MKL (sequential)
5) https://gist.github.com/ronert/5645598R 3.01 compiled with gcc and
gfortran using Intel MKL (threaded)
6) Https://gist.github.com/ronert/5645607R 3.01 compiled with icc and
ifortran using Intel MKL (threaded)

To measure the speed of the 7 Versions of R I now had (6 compiled, 1
.pkg from CRAN), I used Simon Urbanek´s
http://r.research.att.com/benchmarks/R-benchmark-25.R R Benchmark 2.5. I
let it
execute serially for 8 runs, and then in parallel with 4 cores and
2 runs each (so also 8 in total). Additionally, I let each version of
R carry out a large matrix multiplication (10000 rows and 5000
columns). The full benchmarking script:
https://gist.github.com/ronert/5645691
I have a 2012 iMac with an Intel Core i5 clocked at 2.9 GHz and 16 GB RAM
(Mountain Lion 10.8.3).

The code that does not use mclapply runs fine (and much faster than the
stock R from CRAN), but
whenever mcapply() is invoked, all my compiled versions crash.

Version 1 (Accelerate) gives:

*** caught illegal operation ***
> address 0x7fff8a66a15e, cause 'illegal opcode'
> Traceback:
>  1: solve(crossprod(a), crossprod(a, b))
>  2: solve(crossprod(a), crossprod(a, b))
>  3: system.time({    c <- solve(crossprod(a), crossprod(a, b))})
>  4: FUN(2[[1L]], ...)
>  5: lapp R(10652) malloc: *** error for object 0x10b35e000: pointer being
> freed already on death-row
> *** set a breakpoint in malloc_error_break to debug
> R(10653) malloc: *** error for object 0x10b35e000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug
>  *** caught illegal operation ***
> address 0x7fff8a66a15e, cause 'illegal opcode'
> Traceback:
>  1: solve(crossprod(a), crossprod(a, b))
>  2: solve(crossprod(a), crossprod(a, b))
>  3: system.time({    c <- solve(crossprod(a), crossprod(a, b))})
>  4: FUN(2[[1L]], ...)
>  5: lapply(X = S, FUN = FUN, ...)
>  6: doTryCatch(return(expr), name, parentenv, handler)
>  7: tryCatchOne(expr, names, parentenv, handlers[[1L]])
>  8: tryCatchList(expr, classes, parentenv, handlers)
>  9: tryCatch(expr, error = function(e) {    call <- conditionCall(e)    if
> (!is.null(call)) {        if (identical(call[[1L]], quote(doTryCatch)))
>         call <- sys.call(-4L)        dcall <- deparse(call)[1L]
>  prefix <- paste("Error in", dcall, ": ")        LONG <- 75L        msg <-
> conditionMessage(e)        sm <- strsplit(msg, "\n")[[1L]]        w <- 14L
> + nchar(dcall, type = "w") + nchar(sm[1L], type = "w")        if (is.na(w))
>             w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L],
>     type = "b")        if (w > LONG)             prefix <- paste0(prefix,
> "\n  ")    }    else prefix <- "Error : "    msg <- paste0(prefix,
> conditionMessage(e), "\n")    .Internal(seterrmessage(msg[1L]))    if
> (!silent && identical(getOption("show.error.messages"),         TRUE)) {
>      cat(msg, file = stderr())        .Internal(printDeferredWarnings())
>  }    invisible(structure(msg, class = "try-error", condition = e))})
> 10: try(lapply(X = S, FUN = FUN, ...), silent = TRUE)
> 11: sendMaster(try(lapply(X = S, FUN = FUN, ...), silent = TRUE))
> 12: FUN(1:4[[1L]], ...)
> 13: lapply(seq_len(cores), inner.do)
> 14: mclapply(runs, rbenchmark, mc.cores = 4)
> 15: system.time(mclapply(runs, rbenchmark, mc.cores = 4))
> Possible actions:
> 1: abort (with core dump, if enabled)
> 2: normal R exit
> 3: exit R without saving workspace
> 4: exit R saving workspace
> Selection:
>  *** caught illegal operation ***
> address 0x7fff8a66a15e, cause 'illegal opcode'
> Traceback:
>  1: solve(crossprod(a), crossprod(a, b))
>  2: solve(crossprod(a), crossprod(a, b))
>  3: system.time({    c <- solve(crossprod(a), crossprod(a, b))})
>  4: FUN(2[[1L]], ...)
>  5: lapply(X = S, FUN = FUN, ...)
>  6: doTryCatch(return(expr), name, parentenv, handler)
>  7: tryCatchOne(expr, names, parentenv, handlers[[1L]])
>  8: tryCatchList(expr, classes, parentenv, handlers)
>  9: tryCatch(expr, error = function(e) {    call <- conditionCall(e)    if
> (!is.null(call)) {        if (identical(call[[1L]], quote(doTryCatch)))
>         call <- sys.call(-4L)        dcall <- deparse(call)[1L]
>  prefix <- paste("Error in", dcall, ": ")        LONG <- 75L        msg <-
> conditionMessage(e)        sm <- strsplit(msg, "\n")[[1L]]        w <- 14L
> + nchar(dcall, type = "w") + nchar(sm[1L], type = "w")        if (is.na(w))
>             w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L],
>     type = "b")        if (w > LONG)             prefix <- paste0(prefix,
> "\n  ")    }    else prefix <- "Error : "    msg <- paste0(prefix,
> conditionMessage(e), "\n")    .Internal(seterrmessage(msg[1L]))    if
> (!silent && identical(getOption("show.error.messages"),         TRUE)) {
>      cat(msg, file = stderr())        .Internal(printDeferredWarnings())
>  }    invisible(structure(msg, class = "try-error", condition = e))})
> 10: try(lapply(X = S, FUN = FUN, ...), silent = TRUE)
> 11: sendMaster(try(lapply(X = S, FUN = FUN, ...), silent = TRUE))
> 12: FUN(1:4[[4L]], ...)
> 13: lapply(seq_len(cores), inner.do)
> 14: mclapply(runs, rbenchmark, mc.cores = 4)
> 15: system.time(mclapply(runs, rbenchmark, mc.cores = 4))
> Possible actions:
> 1: abort (with core dump, if enabled)
> 2: normal R exit
> 3: exit R without saving workspace
> 4: exit R saving workspace
> Selection:


Version 2 (OpenMP):

2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.59799999999998
> 2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.57450000000003
> 2800x2800 cross-product matrix (b = a' * a)_________ (sec):  1.7765
> 2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.59699999999998
> R(10707) malloc: *** error for object 0x111bfb000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug
> R(10708) malloc: *** error for object 0x109bf3000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug
> R(10706) malloc: *** error for object 0x109b6b000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug
> R(10705) malloc: *** error for object 0x109d52000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug
>    user  system elapsed
>  34.526   2.612  18.223
> [1] "Test finished\n"
> Warning messages:
> 1: In remove("a", "b") : object 'a' not found
> 2: In remove("a", "b") : object 'b' not found


Version 3 (gcc, MKL, sequential):

8 800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.67999999999995
> 2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.78199999999998
> 2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.64849999999996
>  *** caught bus error ***
> address 0x7fb0c0d019a0, cause 'non-existent physical address'
> Traceback:
>  1: crossprod(a)
>  2: crossprod(a)
> Possible actions:
> 1: abort (with core dump, if enabled)
> 2: normal R exit
> 3: exit R without saving workspace
> 4: exit R saving workspace
> Selection: R(10822) malloc: *** error for object 0x1107aa000: pointer
> being freed already on death-row
> *** set a breakpoint in malloc_error_break to debug
> R(10823) malloc: *** error for object 0x110a08000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug


Version 4 (icc, MKL, sequential):

Selection: 2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  0.78249999999997
>  *** caught illegal operation ***
> address 0x7fff8a66a15e, cause 'illegal opcode'
> Traceback:
>  1: solve(crossprod(a), crossprod(a, b))
>  2: solve(crossprod(a), crossprod(a, b))
>  3: system.time({    c <- solve(crossprod(a), crossprod(a, b))})
>  4: FUN(2[[1L]], ...)
>  5: lapply(X = S, FUN = FUN, ...)
>  6: doTryCatch(return(expr), name, parentenv, handler)
>  7: tryCatchOne(expr, names, parentenv, handlers[[1L]])
>  8: tryCatchList(expr, classes, parentenv, handlers)
>  9: tryCatch(expr, error = function(e) {    call <- conditionCall(e)    if
> (!is.null(call)) {        if (identical(call[[1L]], quote(doTryCatch)))
>         call <- sys.call(-4L)        dcall <- deparse(call)[1L]
>  prefix <- paste("Error in", dcall, ": ")        LONG <- 75L        msg <-
> conditionMessage(e)        sm <- strsplit(msg, "\n")[[1L]]        w <- 14L
> + nchar(dcall, type = "w") + nchar(sm[1L], type = "w")        if (is.na(w))
>             w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L],
>     type = "b")        if (w > LONG)             prefix <- paste0(prefix,
> "\n  ")    }    else prefix <- "Error : "    msg <- paste0(prefix,
> conditionMessage(e), "\n")    .Internal(seterrmessage(msg[1L]))    if
> (!silent && identical(getOption("show.error.messages"),         TRUE)) {
>      cat(msg, file = stderr())        .Internal(printDeferredWarnings())
>  }    invisible(structure(msg, class = "try-error", condition = e))})
> 10: try(lapply(X = S, FUN = FUN, ...), silent = TRUE)
> 11: sendMaster(try(lapply(X = S, FUN = FUN, ...), silent = TRUE))
> 12: FUN(1:4[[4L]], ...)
> 13: lapply(seq_len(cores), inner.do)
> 14: mclapply(runs, rbenchmark, mc.cores = 4)
> 15: system.time(mclapply(runs, rbenchmark, mc.cores = 4))
> Possible actions:
> 1: abort (with core dump, if enabled)
> 2: normal R exit
> 3: exit R without saving workspace
> 4: exit R saving workspace
> Selection: R(10979) malloc: *** error for object 0x100d57000: pointer
> being freed already on death-row
> *** set a breakpoint in malloc_error_break to debug
> R(10976) malloc: *** error for object 0x10108b000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug


Version 5 (gcc, MKL, threaded):

2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.45550000000003
> 2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.51499999999999
> 2800x2800 cross-product matrix (b = a' * a)_________ (sec):  1.37
> 2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  1.52600000000001
> R(10887) malloc: *** error for object 0x1013e2000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug
> R(10888) malloc: *** error for object 0x102107000: pointer being freed was
> not allocated
> *** set a breakpoint in malloc_error_break to debug
> R(10886) malloc: *** error for object 0x7fd33b43e398: incorrect checksum
> for freed object - object was probably modified after being freed.
> *** set a breakpoint in malloc_error_break to debug
> R(10886) malloc: *** error for object 0x7fd33b43e398: incorrect checksum
> for freed object - object was probably modified after being freed.
> *** set a breakpoint in malloc_error_break to debug
> R(10886) malloc: *** error for object 0x7fd33b43e398: incorrect checksum
> for freed object - object was probably modified after being freed.
> *** set a breakpoint in malloc_error_break to debug
> R(10889) malloc: *** error for object 0x10135a000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug
>    user  system elapsed
>  35.249   2.735  23.913
> [1] "Test finished\n"
> Warning messages:
> 1: In remove("a", "b") : object 'a' not found
> 2: In remove("a", "b") : object 'b' not found


Version 6 (icc, MKL, threaded):

2800x2800 cross-product matrix (b = a' * a)_________ (sec):
>  0.861499999999978
> R(10984) malloc: *** error for object 0x7f8029470e90: pointer being freed
> was not allocated
> *** set a breakpoint in malloc_error_break to debug
> R(10985) malloc: *** error for object 0x102287000: pointer being freed was
> not allocated
> *** set a breakpoint in malloc_error_break to debug
> R(10982) malloc: *** error for object 0x1020f2000: pointer being freed
> already on death-row
> *** set a breakpoint in malloc_error_break to debug


Thank you and best regards
Ronert Obst

	[[alternative HTML version deleted]]

