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

Reply via email to