2012-12-17 14 views
5

Mam następujący inline funkcję CythonCython: Inline Funkcja nie czystym C

cpdef inline int c_rate2recs_2(int maxNN,int idx): 
    cdef int out=idx%maxNN 
    return out 

jednak przekłada się to

/* 
* return out 
* 
* cpdef inline int c_rate2recs_2(int maxNN,int idx):    # <<<<<<<<<<<<<< 
* cdef int out=idx%maxNN 
* return out 
*/ 

static PyObject *__pyx_pw_6kmc_cy_5c_rate2recs_2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ 
static CYTHON_INLINE int __pyx_f_6kmc_cy_c_rate2recs_2(int __pyx_v_maxNN, int __pyx_v_idx, CYTHON_UNUSED int __pyx_skip_dispatch) { 
    int __pyx_v_out; 
    int __pyx_r; 
    __Pyx_TraceDeclarations 
    __Pyx_RefNannyDeclarations 
    __Pyx_RefNannySetupContext("c_rate2recs_2", 0); 
    __Pyx_TraceCall("c_rate2recs_2", __pyx_f[0], 984); 

/* 
* return out 
* 
* cpdef inline int c_rate2recs_2(int maxNN,int idx):    # <<<<<<<<<<<<<< 
* cdef int out=idx%maxNN 
* return out 
*/ 

static PyObject *__pyx_pf_6kmc_cy_4c_rate2recs_2(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_maxNN, int __pyx_v_idx) { 
    PyObject *__pyx_r = NULL; 
    __Pyx_TraceDeclarations 
    __Pyx_RefNannyDeclarations 
    __Pyx_RefNannySetupContext("c_rate2recs_2", 0); 
    __Pyx_TraceCall("c_rate2recs_2", __pyx_f[0], 984); 
    __Pyx_XDECREF(__pyx_r); 
    __pyx_t_1 = PyInt_FromLong(__pyx_f_6kmc_cy_c_rate2recs_2(__pyx_v_maxNN, __pyx_v_idx, 0)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 
    __Pyx_GOTREF(__pyx_t_1); 
    __pyx_r = __pyx_t_1; 
    __pyx_t_1 = 0; 
    goto __pyx_L0; 

    __pyx_r = Py_None; __Pyx_INCREF(Py_None); 
    goto __pyx_L0; 
    __pyx_L1_error:; 
    __Pyx_XDECREF(__pyx_t_1); 
    __Pyx_AddTraceback("kmc_cy.c_rate2recs_2", __pyx_clineno, __pyx_lineno, __pyx_filename); 
    __pyx_r = NULL; 
    __pyx_L0:; 
    __Pyx_XGIVEREF(__pyx_r); 
    __Pyx_TraceReturn(__pyx_r); 
    __Pyx_RefNannyFinishContext(); 
    return __pyx_r; 
} 

Ponieważ jestem całkiem nowy w branży Cython, chciałbym wiedzieć, jak pozbyć się większości poleceń Pythona (cython -a oznacza to inline jako całkiem odległe od czystego C).

+2

Czy próbowałeś z '' cdef' zamiast 'cpdef'? Myślałem, że z 'cpdef' będzie to tylko C dla funkcji C. – tiago

+0

Dzięki temu rozwiązałem mój problem. Jednak wzrost wydajności w tym przypadku był pomijalny – bios

+0

dla tak małej funkcji, że lepiej nie mieć funkcji. Wywołania funkcji dodają narzut. – tiago

Odpowiedz

3

Ponieważ jestem całkiem nowy w branży Cython, chciałbym wiedzieć, jak pozbyć się większość poleceń Pythona (Cython -a flagi to inline jako dość daleko od czystego C)

Sztuką jest to, że jeśli możesz zadzwonić do swojej funkcji nogil;

cpdef inline int c_rate2recs_2(int maxNN,int idx) nogil: 
    cdef int out=idx%maxNN 
    return out 

to, co zobaczysz na żółto, nie jest generalnie używane w Pythonie. Może to być na przykład przypadek błędu lub inne rodzaje łagodnego sprawdzania. W przypadku cpdef, nie tylko jest wykonywana funkcja czystego C, alias Pythona jest tworzony do wywoływania z zakresu Pythona. Nie wpłynie to na prędkości.

W tym przypadku niektóre czasy względem ręcznie podkreślonej pętli nie wykazały spowolnień, a usunięcie inline również nie spowodowało upływu czasu. Wyobrażam sobie, że sprawa trudniejsza do zoptymalizowania może mieć inną charakterystykę, ale kluczem jest profil.

Wreszcie, przyspieszenie i usunięcie niektórych błędów można sprawdzić, korzystając z compiler directives.