[Rcpp-commits] r1650 - in pkg/Rcpp/inst/examples: . SugarPerformance

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Jun 21 19:34:09 CEST 2010


Author: edd
Date: 2010-06-21 19:34:09 +0200 (Mon, 21 Jun 2010)
New Revision: 1650

Added:
   pkg/Rcpp/inst/examples/SugarPerformance/
   pkg/Rcpp/inst/examples/SugarPerformance/Timer.h
   pkg/Rcpp/inst/examples/SugarPerformance/Timertest.cpp
   pkg/Rcpp/inst/examples/SugarPerformance/vectorOps.R
Log:
first cut at performance for sugar
open issues are compiler warnings from the new Rcpp code as well issues with
the timer class that do not manifest themselves outside of Rcpp use :-/


Added: pkg/Rcpp/inst/examples/SugarPerformance/Timer.h
===================================================================
--- pkg/Rcpp/inst/examples/SugarPerformance/Timer.h	                        (rev 0)
+++ pkg/Rcpp/inst/examples/SugarPerformance/Timer.h	2010-06-21 17:34:09 UTC (rev 1650)
@@ -0,0 +1,100 @@
+
+// Simple timer class based on atimer.h / atimer.cxx found a few years ago at 
+//     http://www.cs.uiowa.edu/~sriram/30/fall03/ 
+//     and attributed to Amir Elaguizy while under GPL
+// That class site is still preserved. Also has a link to a simpler class at duke.edu
+
+#ifndef TIMER_H
+#define TIMER_H
+
+#include <sys/timex.h>			// Probably implies Linux-only ...
+
+int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y);
+
+class Timer {
+public:
+	Timer() { 
+		start_t.time.tv_sec = 0; 
+		start_t.time.tv_usec = 0; 
+		end_t.time.tv_sec = 0; 
+		end_t.time.tv_usec = 0;
+		myCumulative = 0; 
+		myElapsed = 0; 
+	}
+      
+	void Start()  {
+		ntp_gettime(&start_t);
+	}
+
+	void Stop() {
+		ntptimeval result;
+
+		ntp_gettime(&end_t);
+		timeval_subtract(&result.time, &end_t.time, &start_t.time);
+
+		// Calculate elapsed time in seconds
+		myElapsed = (result.time.tv_sec + (result.time.tv_usec / 1000000.0)); 
+		myCumulative += myElapsed;
+	}
+
+	void Reset() {
+		end_t.time.tv_sec = 0;
+		end_t.time.tv_usec = 0;
+		start_t.time.tv_sec = 0;
+		start_t.time.tv_usec = 0;
+		myElapsed = 0;
+		myCumulative = 0;
+	}
+
+	double ElapsedTime()  {
+		return myElapsed;
+	}
+
+	double CumulativeTime() { 
+		return myCumulative;
+	}
+
+
+private:
+	ntptimeval start_t, end_t;
+	double myElapsed;
+	double myCumulative;
+
+	int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) {
+		// NOTE: THIS FUNCTION IS GNU CODE AND IS USED UNDER THE GPL.
+		// Purpose:
+		//   Put the result of subtraction of x & y into result
+		//
+		// Arguments:
+		//   result - the container for the result of subtraction
+		//   x - the ending time
+		//   y - the starting time
+		// 
+		// Return value:
+		//   0 if result is positive (normal state)
+		//   1 if result is negative (error state)
+		
+		// Perform the carry for the later subtraction by updating y.
+		if (x->tv_usec < y->tv_usec) {
+			int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
+			y->tv_usec -= 1000000 * nsec;
+			y->tv_sec += nsec;
+		}
+		if (x->tv_usec - y->tv_usec > 1000000) {
+			int nsec = (x->tv_usec - y->tv_usec) / 1000000;
+			y->tv_usec += 1000000 * nsec;
+			y->tv_sec -= nsec;
+		}
+	
+		// Compute the time remaining to wait.
+		//    tv_usec is certainly positive.
+		result->tv_sec = x->tv_sec - y->tv_sec;
+		result->tv_usec = x->tv_usec - y->tv_usec;
+		
+		// Return 1 if result is negative. 
+		return x->tv_sec < y->tv_sec;
+	}
+};
+
+#endif
+


Property changes on: pkg/Rcpp/inst/examples/SugarPerformance/Timer.h
___________________________________________________________________
Added: svn:eol-style
   + native

Added: pkg/Rcpp/inst/examples/SugarPerformance/Timertest.cpp
===================================================================
--- pkg/Rcpp/inst/examples/SugarPerformance/Timertest.cpp	                        (rev 0)
+++ pkg/Rcpp/inst/examples/SugarPerformance/Timertest.cpp	2010-06-21 17:34:09 UTC (rev 1650)
@@ -0,0 +1,31 @@
+// -*- mode: c++; compile-command: "g++ -Wall -O3 -o Timertest Timertest.cpp" -*-
+
+// from http://www.cs.uiowa.edu/~sriram/30/fall03/
+
+#include <iostream>
+#include <unistd.h>
+#include "Timer.h"
+
+int main() {
+	Timer test;
+
+	std::cout << "Sleeping 2 seconds" << std::endl;
+	test.Start();
+	sleep(2);
+	test.Stop();
+	std::cout << "Sleep lasted for " << test.ElapsedTime() << " seconds." << std::endl;
+	std::cout << "Sleeping 1 second" << std::endl;
+	test.Start();
+	sleep(1);
+	test.Stop();
+	std::cout << "Sleep lasted for " << test.ElapsedTime() << " seconds." << std::endl;
+	std::cout << "Cumulative time is " << test.CumulativeTime() << " seconds." << std::endl;
+	std::cout << "Reseting" << std::endl;
+	test.Reset();
+	std::cout << "Sleeping 2 seconds" << std::endl;
+	test.Start();
+	sleep(2);
+	test.Stop();
+	std::cout << "Sleep lasted for " << test.ElapsedTime() << " seconds." << std::endl;
+	std::cout << "Cumulative time is " << test.CumulativeTime() << " seconds." << std::endl;
+}


Property changes on: pkg/Rcpp/inst/examples/SugarPerformance/Timertest.cpp
___________________________________________________________________
Added: svn:eol-style
   + native

Added: pkg/Rcpp/inst/examples/SugarPerformance/vectorOps.R
===================================================================
--- pkg/Rcpp/inst/examples/SugarPerformance/vectorOps.R	                        (rev 0)
+++ pkg/Rcpp/inst/examples/SugarPerformance/vectorOps.R	2010-06-21 17:34:09 UTC (rev 1650)
@@ -0,0 +1,122 @@
+
+suppressMessages(library(inline))
+suppressMessages(library(Rcpp))
+
+
+# RcppExport SEXP vectorOps(SEXP runss, SEXP xs, SEXP ys) {
+src <- '
+    Rcpp::NumericVector x(xs);
+    Rcpp::NumericVector y(ys);
+    unsigned int runs = Rcpp::as<int>(runss);
+    int n = x.size() ;
+
+    Rcpp::NumericVector res(2);
+    Timer timerOne, timerTwo;
+
+    // approach one
+    timerOne.Start();
+    for (unsigned int i=0; i<runs; i++) {
+        Rcpp::NumericVector res1( n ) ;
+        double x_ = 0.0 ;
+        double y_ = 0.0 ;
+        for( int i=0; i<n; i++){
+            x_ = x[i] ;
+            y_ = y[i] ;
+            if( x_ < y_ ){
+                res1[i] = x_ * x_ ;
+            } else {
+                res1[i] = -( y_ * y_)  ;
+            }
+        }
+    }
+    timerOne.Stop();
+    //double t1 = timerOne.ElapsedTime();
+    res[0] = timerOne.ElapsedTime();
+    //timer.Reset();
+
+    // approach two
+    timerTwo.Start();
+    for (unsigned int i=0; i<runs; i++) {
+        Rcpp::NumericVector res2 = ifelse( x < y, x*x, -(y*y) ) ;
+    }
+    timer.Stop();
+    //double t2 = timerTwo.ElapsedTime();
+    res[1] = timer.ElapsedTime();
+
+    return Rcpp::wrap(res);
+    // FAILS:  return Rcpp::List(Rcpp::Named("one")=Rcpp::wrap(t1),
+    //                           Rcpp::Named("two")=Rcpp::wrap(t2));
+'
+
+
+srcOne <- '
+    Rcpp::NumericVector x(xs);
+    Rcpp::NumericVector y(ys);
+    unsigned int runs = Rcpp::as<int>(runss);
+    int n = x.size() ;
+
+    Timer timer;
+
+    timer.Start();
+    for (unsigned int i=0; i<runs; i++) {
+        Rcpp::NumericVector res1( n ) ;
+        double x_ = 0.0 ;
+        double y_ = 0.0 ;
+        for( int i=0; i<n; i++){
+            x_ = x[i] ;
+            y_ = y[i] ;
+            if( x_ < y_ ){
+                res1[i] = x_ * x_ ;
+            } else {
+                res1[i] = -( y_ * y_)  ;
+            }
+        }
+    }
+    timer.Stop();
+    return Rcpp::wrap( timer.ElapsedTime() );
+'
+
+srcTwo <- '
+    Rcpp::NumericVector x(xs);
+    Rcpp::NumericVector y(ys);
+    unsigned int runs = Rcpp::as<int>(runss);
+
+    Timer timer;
+
+    timer.Start();
+    for (unsigned int i=0; i<runs; i++) {
+        Rcpp::NumericVector res = ifelse( x < y, x*x, -(y*y) ) ;
+    }
+    timer.Stop();
+    return Rcpp::wrap( timer.ElapsedTime() );
+'
+
+
+
+settings <- getPlugin("Rcpp")
+settings$env$PKG_CXXFLAGS <- paste("-I", getwd(), " -O0", sep="")
+
+funOne <- cxxfunction(signature(runss="numeric", xs="numeric", ys="numeric"),
+                      srcOne,
+                      includes='#include "Timer.h"',
+                      plugin="Rcpp",
+                      settings=settings)
+funTwo <- cxxfunction(signature(runss="numeric", xs="numeric", ys="numeric"),
+                      srcTwo,
+                      includes='#include "Timer.h"',
+                      plugin="Rcpp",
+                      settings=settings)
+
+
+x <- runif(1e6)
+y <- runif(1e6)
+runs <- 10
+
+resOne <- funOne(runs, x, y)
+resTwo <- funTwo(runs, x, y)
+cat("Timings: ", resOne, "vs", resTwo, "\n")
+
+# Does order matter?
+resTwo <- funTwo(runs, x, y)
+resOne <- funOne(runs, x, y)
+cat("Timings: ", resOne, "vs", resTwo, "\n")


Property changes on: pkg/Rcpp/inst/examples/SugarPerformance/vectorOps.R
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:eol-style
   + native



More information about the Rcpp-commits mailing list