[Rcpp-commits] r2172 - in pkg/Rcpp/inst: . examples/ConvolveBenchmarks include/Rcpp/vector

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Sep 25 12:19:44 CEST 2010


Author: romain
Date: 2010-09-25 12:19:44 +0200 (Sat, 25 Sep 2010)
New Revision: 2172

Modified:
   pkg/Rcpp/inst/ChangeLog
   pkg/Rcpp/inst/examples/ConvolveBenchmarks/exampleRCode.r
   pkg/Rcpp/inst/include/Rcpp/vector/RangeIndexer.h
Log:
trying loop unrolling, which makes sugar faster than optimized R api code

Modified: pkg/Rcpp/inst/ChangeLog
===================================================================
--- pkg/Rcpp/inst/ChangeLog	2010-09-25 09:49:44 UTC (rev 2171)
+++ pkg/Rcpp/inst/ChangeLog	2010-09-25 10:19:44 UTC (rev 2172)
@@ -6,6 +6,8 @@
     
     * R/*.R: use registration information in many .Call and .External functions
     to speed things up
+    
+    * inst/include/Rcpp/RangeIndexer.h: experimenting with loop unrolling
 
 2010-09-24  Romain Francois <romain at r-enthusiasts.com>
 

Modified: pkg/Rcpp/inst/examples/ConvolveBenchmarks/exampleRCode.r
===================================================================
--- pkg/Rcpp/inst/examples/ConvolveBenchmarks/exampleRCode.r	2010-09-25 09:49:44 UTC (rev 2171)
+++ pkg/Rcpp/inst/examples/ConvolveBenchmarks/exampleRCode.r	2010-09-25 10:19:44 UTC (rev 2172)
@@ -2,8 +2,8 @@
 
 suppressMessages(require(Rcpp))
 set.seed(42)
-a <- rnorm(100)
-b <- rnorm(100)
+a <- rnorm(500)
+b <- rnorm(500)
 
 ## load shared libraries with wrapper code
 dyn.load("convolve2_c.so")
@@ -50,7 +50,7 @@
 
 ## load benchmarkin helper function
 suppressMessages(library(rbenchmark))
-REPS <- 10000L
+REPS <- 2000L
 bm <- benchmark(R_API_optimised(REPS,a,b),
                 R_API_naive(REPS,a,b),
                 Rcpp_Classic(REPS,a,b),

Modified: pkg/Rcpp/inst/include/Rcpp/vector/RangeIndexer.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/vector/RangeIndexer.h	2010-09-25 09:49:44 UTC (rev 2171)
+++ pkg/Rcpp/inst/include/Rcpp/vector/RangeIndexer.h	2010-09-25 10:19:44 UTC (rev 2172)
@@ -22,6 +22,30 @@
 #ifndef Rcpp__vector__RangeIndexer_h
 #define Rcpp__vector__RangeIndexer_h
 
+#define UNROLL_LOOP(OP)                              \
+    const T& input = x.get_ref() ;                   \
+    int __trip_count = (size_) >> 2;                 \
+    int i=0 ;                                        \
+    for ( ; __trip_count > 0 ; --__trip_count) {     \
+        start[i] OP input[i] ; i++ ;                 \
+        start[i] OP input[i] ; i++ ;                 \
+        start[i] OP input[i] ; i++ ;                 \
+        start[i] OP input[i] ; i++ ;                 \
+    }                                                \
+    switch (size_ - i){                              \
+      case 3:                                        \
+          start[i] OP input[i] ; i++ ;               \
+      case 2:                                        \
+          start[i] OP input[i] ; i++ ;               \
+      case 1:                                        \
+          start[i] OP input[i] ; i++ ;               \
+      case 0:                                        \
+      default:                                       \
+          return *this ;                             \
+    }
+
+
+
 namespace internal{
 
 template <int RTYPE, typename VECTOR>
@@ -37,47 +61,27 @@
 		// TODO: size exceptions
 	template <bool NA, typename T>	
 	RangeIndexer& operator=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
-	    const T& input = x.get_ref() ;
-	    for( int i=0; i<size_; i++){
-			start[i] = input[i] ;
-		}
-		return *this ;
+	    UNROLL_LOOP(=)
 	}
 	
 	template <bool NA, typename T>	
 	RangeIndexer& operator+=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
-		const T& input = x.get_ref() ;
-	    for( int i=0; i<size_; i++){
-			start[i] += input[i] ;
-		}
-		return *this ;
+		 UNROLL_LOOP(+=)
 	}
 	
 	template <bool NA, typename T>	
 	RangeIndexer& operator*=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
-		const T& input = x.get_ref() ;
-	    for( int i=0; i<size_; i++){
-			start[i] *= input[i] ;
-		}
-		return *this ;
+		UNROLL_LOOP(*=)
 	}
 	
 	template <bool NA, typename T>	
 	RangeIndexer& operator-=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
-		const T& input = x.get_ref() ;
-	    for( int i=0; i<size_; i++){
-			start[i] -= input[i] ;
-		}
-		return *this ;
+		UNROLL_LOOP(-=)
 	}
 	
 	template <bool NA, typename T>	
 	RangeIndexer& operator/=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
-		const T& input = x.get_ref() ;
-	    for( int i=0; i<size_; i++){
-			start[i] /= input[i] ;
-		}
-		return *this ;
+		UNROLL_LOOP(/=)
 	}
 	
 	inline Proxy operator[]( int i ){
@@ -95,4 +99,6 @@
 	
 }
 
+#undef UNROLL_LOOP
+
 #endif



More information about the Rcpp-commits mailing list