ok, so after playing around with the values of e1 and e2 in these expressions.
F = ((f1**2)**(1/e2) + (f2**2)**(1/e2))**(e2/e1) + (f3**2)**(1/e1) temperr = (C4 * (F**(e1) - 1))**2 the cython code executes just a fast a numpy, I guess I cant get any faster because the bottleneck is the calls to pow. And depending on the value of the exponent, it can be REALLY slow. see here: http://sourceware.org/ml/libc-help/2009-01/msg00003.html so moral of the story, if you have a numpy script that makes repeated use of pow you probably wont speed it up with cython, because pow is a huge bottleneck. Cheers, Chris On Tue, Sep 29, 2009 at 7:11 PM, Chris Colbert <[email protected]> wrote: > my big issue here is that these two lines of code, are taking more > time to execute than the entire function as a pure numpy > implementation. And numpy is using the same calls to pow in the > background... > > i just dont get it....but i will figure it out... > > On Tue, Sep 29, 2009 at 7:05 PM, Sturla Molden <[email protected]> wrote: >> Chris Colbert skrev: >>> No, the python ** gets translated to a pow statement by cython. >>> >>> I think the issue is that for some reason, i'm getting stuck in the >>> gcc slow pow function.... >>> >>> if i let e2 and e1 be 1 and replace f**2 (which would call pow) with f*f, >>> >>> my execution time drops to this: >>> 10000 loops, best of 3: 108 µs per loop >>> >>> over 6x improvement just by avoid a few measly pow statements... >>> anyone know why i'm stuck in slowpow? >>> >> pow() is "slow" because it is a general function that can compute any >> power, including pow(x, -231436.74638746238746). It is not restricted to >> integers only. Therefore, >> >> cdef inline double pow0(double x): >> return 1 >> >> cdef inline double pow1(double x): >> return x >> >> cdef inline double pow2(double x): >> return x*x >> >> cdef inline double pow3(double x): >> return x*x*x >> >> is (often) much faster than pow(x,0), pow(x,1), pow(x,2), and pow(x,3). >> >> A Fortran compiler would recognize x**3 as x*x*x and do the "right thing". >> >> In C++, one could use template metaprogramming for this: >> >> template<int n> >> inline double power<n>(double x) >> { >> if (n > 0) >> return x * power<n-1>(x); >> else >> return 1.0 / power<-n>(x); >> } >> >> template<> >> inline double power<1>(double x) >> { >> return x; >> } >> >> template<> >> inline double power<0>(double x) >> { >> return 1; >> } >> >> Which BTW is a really disgusting way of coding... I like Fortran better. >> >> >> >> S.M. >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>> >>> >>> On Tue, Sep 29, 2009 at 6:15 PM, Sturla Molden <[email protected]> wrote: >>> >>>> Sturla Molden skrev: >>>> >>>>> Chris Colbert skrev: >>>>> >>>>> >>>>>> and within that loop it is these statements that take the bulk of the >>>>>> time: >>>>>> >>>>>> F = ((f1**2)**(1/e2) + (f2**2)**(1/e2))**(e2/e1) + (f3**2)**(1/e1) >>>>>> >>>>>> temperr = (C4 * (F**(e1) - 1))**2 >>>>>> >>>>>> and replacing the powers with serial multiplications don't really help >>>>>> any... >>>>>> >>>>>> >>>>>> >>>>> Does this help? >>>>> >>>>> cdef extern from "math.h": >>>>> double pow(double, double) >>>>> >>>>> F = pow(pow((f1*f1),(1/e2)) + pow((f2*f2),(1/e2)),(e2/e1)) \ >>>>> + pow((f3*f3),(1/e1)) >>>>> >>>>> >>>>> >>>> cdef double tmp >>>> >>>> tmp = C4 * (pow(F,e1) - 1) >>>> >>>> temperr = tmp*tmp >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> Cython-dev mailing list >>>> [email protected] >>>> http://codespeak.net/mailman/listinfo/cython-dev >>>> >>>> >>> _______________________________________________ >>> Cython-dev mailing list >>> [email protected] >>> http://codespeak.net/mailman/listinfo/cython-dev >>> >> >> _______________________________________________ >> Cython-dev mailing list >> [email protected] >> http://codespeak.net/mailman/listinfo/cython-dev >> > _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
