[Rcpp-devel] bounds checking disabled for RcppEigen?
Dirk Eddelbuettel
edd at debian.org
Thu Aug 2 02:44:04 CEST 2012
On 1 August 2012 at 17:41, Douglas Bates wrote:
| I don't really think that bounds checking is slowing down this
| calculation. You can make the whole thing run faster by the simple
| expedient of reordering the loops. For me, this version
|
| STLvectortest<-'
| const NumericMatrix X = Rcpp::as<NumericMatrix>(mat);
| int p = X.nrow();
| std::vector<double> V(p*p);
|
| // Copy data into STL vector and Eigen dynamic matrix
| for (int i=0; i<p; ++i){
| for (int j=0; j<p; ++j){
| V[i + j*p] = X(i,j);
| }
| }
|
| double tran = 0.0;
|
| for (int k=0; k<p; ++k){
| for (int j=0; j<p; ++j){
| for (int i=0; i<p; ++i){
| if ((j != i) && (k != i) && (j != k)) {
| tran += V[i + j*p]*V[j + k*p]*V[i + k*p];
| }
| }
| }
| }
|
| return Rcpp::wrap(tran);
| '
|
| is about 40% faster than your version because of localization of access.
|
| As is pointed out in one of the Rcpp vignettes, if you want to make
| accesses to elements of an array fast, you should use pointers. Also,
Well ... it just looks somewhat un-C++-like to me.
Romain and I beat this to death in one of the early example still in the
package as examples/ConvolveBenchmark/ -- started via 'buildAndRun.sh' (as we
may have written this in the pre-inline days). It compares the vector
convolution (from 'Writing R Extensions') in just about every way.
Fastest is ... a solution with loop unrolling. Pointers are on par with
simple class wrapper which inlines operator[].
Dirk
| remove repeated calculations of loop invariants. A good compiler can
| do such loop lifting for you but you might as well do it yourself when
| you this happening. The fastest version I can come up with is
|
| Ptrtest<-'
| const NumericMatrix X(mat);
| int p = X.nrow();
| double *xpt = &X[0];
| double tran = 0.0;
|
| for (int k=0; k<p; ++k){
| double *xk = xpt + k*p;
| for (int j=0; j<p; ++j){
| if (j != k) {
| double *xj = xpt + j*p;
| double xjk = xpt[j + k*p];
| for (int i=0; i<p; ++i){
| if ((i != j) && (i != k)) {
| tran += xj[i] * xjk * xk[i];
| }
| }
| }
| }
| }
|
| return Rcpp::wrap(tran);
| '
| ptr <-cxxfunction(signature(mat="numeric"), Ptrtest, "RcppEigen",
| header, verbose=TRUE)
| _______________________________________________
| 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
--
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
More information about the Rcpp-devel
mailing list