Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64558 - sandbox/SOC/2010/quasi_random/boost/random
From: jvd_at_[hidden]
Date: 2010-08-03 05:14:15


Author: qrng
Date: 2010-08-03 05:14:12 EDT (Tue, 03 Aug 2010)
New Revision: 64558
URL: http://svn.boost.org/trac/boost/changeset/64558

Log:
Exponentiation unrolled after having done the performance tests. Note, that overflows in base do not matter
much.

Text files modified:
   sandbox/SOC/2010/quasi_random/boost/random/faure.hpp | 25 ++++++++++++-------------
   1 files changed, 12 insertions(+), 13 deletions(-)

Modified: sandbox/SOC/2010/quasi_random/boost/random/faure.hpp
==============================================================================
--- sandbox/SOC/2010/quasi_random/boost/random/faure.hpp (original)
+++ sandbox/SOC/2010/quasi_random/boost/random/faure.hpp 2010-08-03 05:14:12 EDT (Tue, 03 Aug 2010)
@@ -72,24 +72,23 @@
   return ilog;
 }
 
-// Implements exponentiation by squaring, for p > ~4 this is computationally
-// more efficient than naïvely multiplying the base with itself repeatedly.
+// Implements unrolled exponentiation by squaring. For p > ~4 this is computationally
+// more efficient than naively multiplying the base with itself repeatedly.
 // In erroneous situations, e.g., integer_pow(0, 0) the function returns 1
 // and does not report the error. This is the intended behavior.
+inline std::size_t mdelta(std::size_t base, std::size_t p)
+{
+ return (p & 1) * base + !(p & 1); // (p & 1) ? base : 1
+}
+
 inline std::size_t integer_pow(std::size_t base, std::size_t p)
 {
   std::size_t result = 1;
- for( ; p != 0; p >>= 1, base *= base )
- {
- // A typical way to implement the multiplication
- // would be something like this:
- // if( p & 1 )
- // result *= base;
- // Apart from being simple this method, however,
- // does not have a lot of other advantages, it is not, especially,
- // friendly to CPU branch prediction routines.
- std::size_t k = (p & 1); // k in {0,1}
- result *= (k * base + !k);
+ for( ; p != 0; p >>= 1, base *= base ) {
+ result *= mdelta(base, p);
+ result *= mdelta(base *= base, p >>= 1);
+ result *= mdelta(base *= base, p >>= 1);
+ result *= mdelta(base *= base, p >>= 1);
   }
   return result;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk