2012-01-17 14 views
11

मैं 1000000 x 100 के एक दो आयामी वैश्विक काम आकार और 1 x 100.ओपनसीएल में स्थानीय मेमोरी कैसे घोषित करें?

__kernel void myKernel(
     const int length, 
     const int height, 
     and a bunch of other parameters) { 

    //declare some local arrays to be shared by all 100 work item in this group 
    __local float LP [length]; 
    __local float LT [height]; 
    __local int bitErrors = 0; 
    __local bool failed = false; 

    //here come my actual computations which utilize the space in LP and LT 
} 

हालांकि यह संकलित करने के लिए मना कर दिया की एक स्थानीय काम के आकार के साथ नीचे OpenCL गिरी चल रहा हूँ, मापदंडों के बाद से length और height संकलन समय पर ज्ञात नहीं हैं। लेकिन यह बिल्कुल सही नहीं है कि यह सही तरीके से कैसे करें। क्या मुझे मेमॉलोक के साथ पॉइंटर्स का उपयोग करना चाहिए? इसे इस तरह से कैसे संभालें कि मेमोरी केवल पूरे वर्क ग्रुप के लिए आवंटित की जाती है और एक बार प्रति कार्य आइटम नहीं?

सभी है कि मैं जरूरत तैरता के 2 सरणियों, 1 पूर्णांक और 1 बूलियन कि पूरे कार्यसमूह (ताकि सभी 100 काम आइटम) के बीच साझा कर रहे हैं।

kernel void myKernel(const int length, const int height, local float* LP, 
        local float* LT, a bunch of other parameters) 

फिर आप एक value के साथ kernelargument सेट: लेकिन मैं किसी भी विधि का यह सही है ...

+0

http://stackoverflow.com/questions/2541929/how-do-i-use-local-memory-in-opencl –

उत्तर

23

यह अपेक्षाकृत सरल है, तो आप तर्क के रूप में स्थानीय सरणियों अपने कर्नेल में पारित कर सकते हैं है खोजने के लिए असफल NULL और एक size आकार आप तर्क (बाइट में) के लिए आवंटित करना चाहते करने के लिए बराबर। इसलिए यह होना चाहिए:

clSetKernelArg(kernel, 2, length * sizeof(cl_float), NULL); 
clSetKernelArg(kernel, 2, height* sizeof(cl_float), NULL); 

स्थानीय स्मृति हमेशा कार्यसमूह (के रूप में निजी के खिलाफ) द्वारा साझा किया जाता है, इसलिए मुझे लगता है कि bool और int ठीक होना चाहिए, लेकिन नहीं तो आप हमेशा तर्क के रूप में उन पारित कर सकते हैं।

वास्तव में आपकी समस्या से संबंधित नहीं है (और यह आवश्यक नहीं है, क्योंकि मुझे नहीं पता कि आप इसे किस हार्डवेयर पर चलाने की योजना बना रहे हैं), लेकिन कम से कम gpus वर्किंग्स की तरह कण नहीं है जो किसी विशेष शक्ति के एकाधिक नहीं हैं दोनों में से (मुझे लगता है कि AMD के लिए NVIDIA के लिए 32, 64) था, जिसका अर्थ है कि शायद 128 आइटम, जिनमें से पिछले 28 मूल रूप से बर्बाद हो जाते हैं साथ कार्य समूहों का निर्माण करेगा। तो यदि आप जीपीयू पर ओपनक्ल चला रहे हैं तो यह प्रदर्शन में मदद कर सकता है यदि आप सीधे आकार 128 के वर्कग्रुप का उपयोग करते हैं (और वैश्विक कार्य आकार को उचित रूप से बदलते हैं)

एक साइड नोट के रूप में: मुझे कभी समझा नहीं गया कि हर कोई kernel, local and global के लिए अंडरस्कोर संस्करण का उपयोग क्यों करता है, मेरे लिए बहुत ज्यादा लग रहा है।

+0

हममम ... तो कैसे मैं इस कार्यसमूह आकार समस्या को हल करना चाहिए?100 नाममात्र मूल्य है, यह समस्या के सटीक उदाहरण के आधार पर भिन्न हो सकता है, लेकिन मुझे वैश्विक इनपुट के प्रत्येक 1x100 सबब्लॉक के लिए इन स्थानीय मेमोरी चर की आवश्यकता है। मुझे लगता है कि एक चर चरम 1x100 सबब्लॉक के बीच साझा करने का कोई तरीका नहीं है यदि वह सबब्लॉक कार्यसमूह नहीं है? (और साइड नोट के लिए, मैंने __ के बिना कभी कोशिश नहीं की, संकेत के लिए धन्यवाद!) – user1111929

+0

मुझे शायद स्मृति के लिए दो-आयामी सरणी पारित करनी चाहिए, लेकिन मैं यह कैसे कर सकता हूं? मैं 'clSetKernelArg (कर्नेल, 2, लंबाई * local_work_size [0] * sizeof (cl_float), NULL) के साथ कुछ पास कर सकता हूं; 'लेकिन यह एक आयामी सरणी है। यह संभवतः 2-आयामी बनाने के लिए बेहतर होगा, या नहीं? – user1111929

+0

इसके अलावा, बूल और int ठीक नहीं थे, मुझे एक त्रुटि मिलती है: परिवर्तनीय "bitErrors" प्रारंभ नहीं किया जा सकता है। यदि मैं इसे उपरोक्त अपने स्थानीय विवरणों से प्रतिस्थापित करता हूं, तो मुझे 'त्रुटि मिलती है: नामित पता स्थान में पैरामीटर आवंटित नहीं किया जा सकता है'। बेशक मैं इसे लंबाई 1 की सरणी बना सकता हूं, लेकिन यह वास्तव में सबसे सुंदर समाधान नहीं है ... :-) – user1111929

1

आप कर्नेल के बाहर अपने सभी स्थानीय स्मृति को आबंटित करने, विशेष रूप से जब यह एक सरणी के बजाय एक सरल चर रहा है नहीं है।

कारण यह है कि आपके कोड संकलन नहीं कर सकता कि OpenCL स्थानीय स्मृति आरंभीकरण का समर्थन नहीं करता है। यह दस्तावेज़ में निर्दिष्ट है (https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/local.html)। यह भी CUDA (Is there a way of setting default value for shared memory array?)


ps में संभव नहीं है: ग्रिजली से जवाब काफी अच्छा है और यह बेहतर होगा अगर मैं एक टिप्पणी के रूप में पोस्ट कर सकते हैं, लेकिन मैं प्रतिष्ठा नीति द्वारा प्रतिबंधित कर रहा हूँ। माफ़ कीजिये।

0

आप भी इस तरह अपने सरणियों की घोषणा कर सकता है:

__local float LP[LENGTH]; 

और अपने कर्नेल संकलन में के रूप में एक परिभाषित लंबाई गुजरती हैं।

clBuildProgram(program, 0, NULL, "-DLENGTH=128", NULL, NULL); 
संबंधित मुद्दे