2016-08-19 6 views
8

मैं साइथन के prange के साथ कुछ मीट्रिक कंप्यूटेशंस के प्रदर्शन में सुधार करने की कोशिश कर रहा हूं। यहाँ मेरी कोड हैं:साइथन की प्रस्तुति प्रदर्शन में सुधार नहीं कर रही

def shausdorff(float64_t[:,::1] XA not None, float64_t[:,:,::1] XB not None): 
    cdef: 
     Py_ssize_t i 
     Py_ssize_t n = XB.shape[2] 
     float64_t[::1] hdist = np.zeros(n) 

    #arrangement to fix contiguity 
    XB = np.asanyarray([np.ascontiguousarray(XB[:,:,i]) for i in range(n)]) 

    for i in range(n): 
     hdist[i] = _hausdorff(XA, XB[i]) 
    return hdist 

def phausdorff(float64_t[:,::1] XA not None, float64_t[:,:,::1] XB not None): 
    cdef: 
     Py_ssize_t i 
     Py_ssize_t n = XB.shape[2] 
     float64_t[::1] hdist = np.zeros(n) 

    #arrangement to fix contiguity (EDITED) 
    cdef float64_t[:,:,::1] XC = np.asanyarray([np.ascontiguousarray(XB[:,:,i]) for i in range(n)]) 

    with nogil, parallel(num_threads=4): 
     for i in prange(n, schedule='static', chunksize=1): 
      hdist[i] = _hausdorff(XA, XC[i]) 
    return hdist 

मूल रूप से, प्रत्येक चरण में हॉसडॉर्फ़ मीट्रिक XA और प्रत्येक XB[i] के बीच की जाती है।

cdef inline float64_t _hausdorff(float64_t[:,::1] XA, float64_t[:,::1] XB) nogil: 
    ... 

मेरी समस्या यह है कि दोनों अनुक्रमिक shausdorff और समानांतर phausdorff एक ही समय है: यहाँ _hausdorff समारोह के हस्ताक्षर है। इसके अलावा, ऐसा लगता है कि phausdorff कोई भी धागा नहीं बना रहा है।

तो मेरा सवाल यह है कि मेरे कोड में क्या गलत है, और मैं थ्रेडिंग काम करने के लिए इसे कैसे ठीक कर सकता हूं।

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Build import cythonize 
from Cython.Distutils import build_ext 

ext_modules=[ 
    Extension("custom_metric", 
       ["custom_metric.pyx"], 
       libraries=["m"], 
       extra_compile_args = ["-O3", "-ffast-math", "-march=native", "-fopenmp" ], 
       extra_link_args=['-fopenmp'] 
      ) 
] 

setup( 
    name = "custom_metric", 
    cmdclass = {"build_ext": build_ext}, 
    ext_modules = ext_modules 
) 

संपादित करें: 1: custom_metric.html

संपादित करें 2: यहाँ एचटीएमएल cython -a द्वारा उत्पन्न करने के लिए एक कड़ी है

यहाँ मेरी setup.py है यहाँ कैसे कॉल करने के लिए पर एक उदाहरण है संबंधित फ़ंक्शंस (आपको the Cython file पहले संकलित करने की आवश्यकता है)

import custom_metric as cm 
import numpy as np 

XA = np.random.random((9000, 210)) 
XB = np.random.random((1000, 210, 9)) 

#timing 'parallel' version 
%timeit cm.phausdorff(XA, XB) 

#timing sequential version 
%timeit cm.shausdorff(XA, XB) 
+0

क्या आपने 'prange' के लूप-बॉडी के भीतर' omp_get_thread_num() 'के बराबर प्रिंट करने का प्रयास किया है। Http://cython.readthedocs.io/en/latest/src/userguide/parallelism.html – Harald

+2

देखें कि 'एक्सबी' एक पायथन ऑब्जेक्ट है? एनोटेशन के साथ 'cython -a custom_metric.pyx' चलाएं। – cgohlke

+0

क्या कोई फोकसॉर्फ ''cython.boundscheck (झूठा)' और' @ cython.wraparound (झूठा) 'से सजाया गया है, तो कोई बदलाव है? –

उत्तर

4

मुझे लगता है कि समानांतरता काम कर रही है, लेकिन समानांतरता का अतिरिक्त ओवरहेड उस समय तक खा रहा है जब वह बच जाएगा। अगर मैं अलग-अलग आकार सरणियों के साथ की कोशिश तो मैं समानांतर संस्करण

XA = np.random.random((900, 2100)) 
XB = np.random.random((100, 2100, 90)) 

यहाँ समानांतर संस्करण ~ 2/3 लेता है जो निश्चित रूप से isn 'मेरे लिए धारावाहिक संस्करण, के समय की एक गति को देखने के लिए शुरू करते हैं टी 1/4 आप उम्मीद करेंगे, लेकिन कम से कम कुछ लाभ दिखाता है। (

XB = np.asanyarray([np.ascontiguousarray(XB[:,:,i]) for i in range(n)]) 

XB = np.ascontiguousarray(np.transpose(XB,[2,0,1])) 

साथ यह दोनों समानांतर और गैर समानांतर कार्यों को गति काफी काफी:


ही एक सुधार मैं पेशकश कर सकते हैं कोड है कि ठीक करता है समीपता को बदलने के लिए है आपके द्वारा मूल रूप से दिए गए सरणी के साथ 2 का कारक)। यह थोड़ा और स्पष्ट करता है कि prange में आपको ओवरहेड द्वारा धीमा कर दिया जा रहा है - धारावाहिक संस्करण वास्तव में आपके उदाहरण में सरणी के लिए तेज़ है।

+0

(समुदाय विकी के रूप में पोस्ट किया गया क्योंकि यह एक समाधान प्रस्तुत नहीं करता है इसलिए मैं इसे बक्षीस के लिए विवाद से हटाना चाहता था) – DavidW

संबंधित मुद्दे