2010-08-08 14 views
5

जब मैंने ओपनसीएल में प्रोग्रामिंग शुरू की, तो मैंने अपने कर्नेल को डेटा प्रदान करने के लिए निम्न दृष्टिकोण का उपयोग किया:ओपनसीएल में मेमोरी प्रबंधन

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE, object_size, NULL, NULL); 
clEnqueueWriteBuffer(cl_queue, buff, CL_TRUE, 0, object_size, (void *) object, NULL, NULL, NULL); 

यह स्पष्ट रूप से मुझे अपने डेटा को खंडों में विभाजित करने की आवश्यकता है, यह सुनिश्चित करना कि प्रत्येक खंड डिवाइस मेमोरी में फिट होगा। Computations प्रदर्शन करने के बाद, मैं clEnqueueReadBuffer() के साथ डेटा पढ़ा होगा। हालांकि, किसी बिंदु पर मुझे एहसास हुआ कि मैं केवल निम्न पंक्ति का उपयोग कर सकता हूं:

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, object_size, (void*) object, NULL); 

ऐसा करने पर, डेटा का विभाजन अप्रचलित हो गया। और मेरे आश्चर्य के लिए, मुझे प्रदर्शन में एक बड़ा बढ़ावा मिला। यह कुछ है जो मुझे समझ में नहीं आता है। एक होस्ट पॉइंटर का उपयोग करते समय मुझे मिली, डिवाइस मेमोरी कैश के रूप में काम कर रही है, लेकिन प्रोसेसिंग के लिए अभी भी सभी डेटा कॉपी करने की आवश्यकता है और फिर एक बार समाप्त होने पर मुख्य मेमोरी पर कॉपी किया गया है। एक स्पष्ट प्रति का उपयोग कैसे करें (clEnqueRead/WriteBuffer) परिमाण धीमा का एक आदेश है, जब मेरे दिमाग में यह मूल रूप से वही होना चाहिए? क्या मैं कुछ भूल रहा हूँ?

धन्यवाद।

उत्तर

2

हाँ, आप clEnqueueWriteBuffer कॉल में CL_TRUE वंचित रह जाएंगे। यह लेखन ऑपरेशन अवरुद्ध करता है, जो प्रतिलिपि बनाते समय सीपीयू को रोकता है। होस्ट पॉइंटर का उपयोग करके, ओपनसीएल कार्यान्वयन इसे एसिंक्रोनस बनाकर कॉपी को "अनुकूलित" कर सकता है, इस प्रकार समग्र रूप से प्रदर्शन बेहतर होता है।

ध्यान दें कि यह सीएल कार्यान्वयन पर निर्भर करता है, और कोई गारंटी नहीं है कि तेजी से/बराबर/धीमी हो जाएगा नहीं है।

+0

मैं clEnqueueRead/WriteBuffer पर अवरुद्ध ध्वज के बारे में पता कर रहा हूँ। हालांकि जब मैंने उपायों का पालन किया, तो मैंने एक क्लिनिशिश का इस्तेमाल किया (कम से कम मुझे यकीन है कि मैंने किया है), जो अवरुद्ध ध्वज के समान प्रभाव होना चाहिए, या नहीं? यह निश्चित रूप से केवल तभी होता है जब डेटा की एक ही मात्रा संसाधित हो। एचएम, हो सकता है कि सीएल कार्यान्वयन किसी ऑब्जेक्ट का हिस्सा छोड़ने के लिए पर्याप्त स्मार्ट हो जिसे एक्सेस नहीं किया गया है (इसमें से कुछ 70%) ... वैसे भी धन्यवाद! – VHristov

1

कुछ मामलों में सीपीयू और GPU ही शारीरिक DRAM स्मृति साझा कर सकते हैं। उदाहरण के लिए, यदि स्मृति ब्लॉक को संतुष्ट करता है सीपीयू और GPU संरेखण नियम तो इंटेल सीपीयू और GPU के बीच शारीरिक DRAM साझा करने की अनुमति के रूप में व्याख्या CL_MEM_USE_HOST_PTR, इसलिए वहाँ डेटा का कोई वास्तविक नकल है। जाहिर है, यह बहुत तेज़ है!

यहाँ एक कड़ी है कि यह बताता है:

https://software.intel.com/en-us/articles/getting-the-most-from-opencl-12-how-to-increase-performance-by-minimizing-buffer-copies-on-intel-processor-graphics

पुनश्च मैं जानता हूँ कि मेरा जवाब अब तक ओपी के लिए बहुत पुराना है, लेकिन अन्य पाठकों रुचि हो सकती है।

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