[Rcpp-devel] Significant difference in performance when computing Ax
Avraham Adler
avraham.adler at gmail.com
Fri Apr 25 19:43:16 CEST 2014
There is actually one other command to test, `crossprod`, or in this case
`tcrossprod(x, A)`.
Following your code, first run and ensure TRUE is returned.
d <- 2000
A <- matrix(1.0*(1:d^2),nrow=d)
x <- 1.0*(1:d)
all.equal(A%*%x, tcrossprod(x, A), mvprod1(A,x), mvprod2(A,x))
Now, using an i7-3740QM 2.7Ghz CPU with 8GB of RAM as a testbed on Windows
7 (with R & Rcpp compiled from source throwing "-march=core-avx-i -O3
-std=gnu++0x --param l1-cache-line-size=64 --param l1-cache-size=32 --param
l2-cache-size=256" FWIW) I get the following timings:
microbenchmark(A%*%x, tcrossprod(x, A), mvprod1(A, x), mvprod2(A, x), times
= 1000L, control = list(order = 'block'))
Unit: milliseconds
expr min lq median uq max neval
A %*% x 13.183992 13.242965 13.269027 13.317917 16.680117 1000
tcrossprod(x, A) 6.967139 6.991869 7.004424 7.020214 9.795921 1000
mvprod1(A, x) 43.089952 43.134848 43.163953 43.489824 45.129644 1000
mvprod2(A, x) 4.564480 4.883693 4.911848 4.928208 7.435495 1000
So the crossprod function is decently optimized as it is, but the prod2 is
still faster.
Thanks for idea and post!
Avi
On Fri, Apr 25, 2014 at 12:47 PM, Søren Højsgaard <sorenh at math.aau.dk>wrote:
> Dear all,
>
> When forming the matrix-vector-product one can form the inner products
> between As rows and x (mvprod1 below) or form a linear combination of As
> columns (mvprod2 below). The difference in computing time is striking (at
> least for me) for large matrices and it really illustrates the “caching
> issue” (I assume):
>
>
>
> > microbenchmark(mvprod1(A,x), mvprod2(A,x), A%*%x)
>
> Unit: milliseconds
>
> expr min lq median
> uq max neval
>
> mvprod1(A, x) 35.783812 36.310956 36.600186 36.991113 38.922889 100
>
> mvprod2(A, x) 4.408892 4.436882 4.475368 4.568668 5.477176 100
>
> A %*% x 8.514091 8.592230 8.734978 8.811951
> 9.738653 100
>
>
>
> Just wanted to share this!
>
> Cheers
>
> Søren
>
>
>
>
>
>
>
> #include <Rcpp.h>
>
> using namespace Rcpp;
>
>
>
> //[[Rcpp::export]]
>
> NumericVector mvprod1 (NumericMatrix A, NumericVector x){
>
> int nrA=A.nrow(), ncA=A.ncol(), i, j;
>
> NumericVector y(nrA);
>
> for (i=0; i<nrA; ++i){
>
> for (j=0; j<ncA; ++j){
>
> y[i] += A(i,j)*x[j];
>
> }
>
> }
>
> return y;
>
> }
>
>
>
> //[[Rcpp::export]]
>
> NumericVector mvprod2 (NumericMatrix A, NumericVector x){
>
> int nrA=A.nrow(), ncA=A.ncol(), i, j;
>
> NumericVector y(nrA);
>
> for (j=0; j<ncA; ++j){
>
> for (i=0; i<nrA; ++i){
>
> y[i] += A(i,j)*x[j];
>
> }
>
> }
>
> return y;
>
> }
>
>
>
>
>
>
>
> /*** R
>
> d <- 5
>
> A <- matrix(1.0*(1:d^2),nrow=d)
>
> x <- 1.0*(1:d)
>
>
>
> A%*%x
>
> mvprod1(A,x)
>
> mvprod2(A,x)
>
>
>
> d <- 2000
>
> A <- matrix(1.0*(1:d^2),nrow=d)
>
> x <- 1.0*(1:d)
>
>
>
> library(microbenchmark)
>
> microbenchmark(mvprod1(A,x), mvprod2(A,x), A%*%x)
>
> */
>
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20140425/dc044337/attachment.html>
More information about the Rcpp-devel
mailing list