Boost logo

Boost Users :

Subject: Re: [Boost-users] [math][special_functions] Why is cbrt(x) slower than pow(x, 1/3)?
From: Rune Lund Olesen (rune.olesen_at_[hidden])
Date: 2010-01-13 11:03:46


Are you getting the same results from the different tests (the actual
results) ?

As far as i can see from the documentation, the boost function "math::cbrt"
allows you to define the precision used.

In the generel case, precision used can really impact performance.

Maybe look into what precision the other methods are using if its not the
same.

Kind regards and please post any findings.

On Wed, Jan 13, 2010 at 11:36 AM, Tim Odenthal <Tim.Odenthal_at_[hidden]
> wrote:

> Hi!
>
> For a (cell) simulation code I have to calculate lots of cubic roots in
> every
> timestep. So I tried to improve performance on my first guess, namely
> pow(x,
> 1/3) using boost::math::cbrt(). To my astonishment, this is much slower
> than
> the original code. I wrote a small test program to check this claim;
> compiling
> with g++ (Ubuntu 4.4.1-4ubuntu9) 4.4.1 (-O3) on a Intel Core i7 CPU I get
> the
> following timings (averaging the time over 10 trials):
> average time to compute 5000000 roots with pow(): 0.603 s.
> average time to compute 5000000 roots with boost::cbrt(): 1.087 s.
> average time to compute 5000000 roots with improved boost::cbrt(): 1.015 s.
> average time to compute 5000000 roots with exp(1/3*log()): 0.541 s.
>
> My "improved" version allows giving the boost::math::cbrt() method a first
> guess instead of taking just the value of the number whose root is to be
> calculated.
>
> Actually, the function I called in this instance 5000000 times does a bit
> more than just calculating the root; I want to calculate the radii of to
> spheres which overlap so, that their combined volume is equal to the volume
> of
> a "mother sphere":
>
> /**
> * @brief calculates the radius of a daughter cell during symmetric
> division,
> * assuming the volume of the mother cell is
> conserved.
> *
> * @param MotherRadius radius of mother cell before division
> * @param Overlap of the two daughter cells, i.e. radius of daughter -
> * distance from center of daughter to middle-plane of
> * both cells
> *
> * @return for positive overlap returns positive radius, for negative
> overlap
> * negative radius
> **/
> double daughterRadiusfOver( double MotherRadius, double Overlap) {
> // r = 1/2 (2 sqrt(R^6-h^3 R^3)-h^3+2 R^3)^(1/3)+h^2/(2 (2 sqrt(R^6-h^3
> R^3)-
> h^3+2 R^3)^(1/3))
> double O3 = Overlap*Overlap*Overlap;
> double M3 = MotherRadius*MotherRadius*MotherRadius;
>
> double step1 = pow(-O3 + 2*sqrt(-O3*M3 + M3*M3) +
> 2*M3,1.0/3.0);//<-- CUBIC
> ROOT HERE!!! Change to:
> // double step1 = boost::math::cbrt(-O3 + 2*sqrt(-O3*M3 + M3*M3) +
> 2*M3);
>
> if ( Overlap < 0 ){
> cerr << "Warning in daughterRadiusfOver: Negative overlap
> given!" <<endl;
> return -(step1 + Overlap*Overlap/step1)*0.5;
> } else {
> return (step1 + Overlap*Overlap/step1)*0.5;
> }
> }
>
> Why is boost::math::cbrt() no improvement for me - or am I using it the
> wrong
> way? For which cases might it be an improvement, or why is it in the
> library?
> It's funny, but I found that std::exp(1/3*std::log(x)) is so far the
> fastest
> way...
>
> Thanks in advance
> Tim
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net