[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