2014-06-11 3 views
15

में पिन की गई मेमोरी/मैप की गई मेमोरी का उपयोग कैसे करें मेरे आवेदन के लिए मेजबान से डिवाइस में स्थानांतरण समय को कम करने के लिए, मैं पिन की गई मेमोरी का उपयोग करना चाहता हूं। NVIDIA's best practices guide मानचित्रण बफ़र्स का प्रस्ताव है और निम्नलिखित कोड का उपयोग कर डेटा लेखन:ओपनसीएल

cDataIn = (unsigned char*)clEnqueueMapBuffer(cqCommandQue, cmPinnedBufIn, CL_TRUE,CL_MAP_WRITE, 0, memSize, 0, NULL, NULL, NULL); 

for(unsigned int i = 0; i < memSize; i++) 
{ 
    cDataIn[i] = (unsigned char)(i & 0xff); 
} 

clEnqueueWriteBuffer(cqCommandQue, cmDevBufIn, CL_FALSE, 0, 
szBuffBytes, cDataIn, 0, NULL, NULL); 

Intel's optimization guide clEnqueueReadBuffer या clEnqueueWriteBuffer के लिए कॉल के बजाय clEnqueueMapBuffer और clEnqueueUnmapBuffer के लिए कॉल उपयोग करने के लिए सिफारिश की।

पिन की गई मेमोरी/मैप किए गए मेमोरी का उपयोग करने का सही तरीका क्या है? क्या enqueueWriteBuffer का उपयोग कर डेटा लिखना आवश्यक है या enqueueMapBuffer पर्याप्त है?

इसके अलावा, CL_MEM_ALLOC_HOST_PTR और CL_MEM_USE_HOST_PTR के बीच क्या अंतर है?

उत्तर

10

यह एक दिलचस्प विषय है कि बहुत कम लोगों का विवरण है। मैं यह निर्धारित करने की कोशिश करूंगा कि यह वास्तव में कैसे काम करता है।

पिन की गई स्मृति एक स्मृति को संदर्भित करती है जो डिवाइस में मौजूद है, मेजबान में मौजूद है, इसलिए इन 2 यादों के बीच एक डीएमए लेखन संभव है। कॉपी प्रदर्शन में वृद्धि। यही कारण है कि यह बफर निर्माण पैरामीटर में CL_MEM_ALLOC_HOST_PTR की जरूरत है।

दूसरी तरफ, CL_MEM_USE_HOST_PTR बफर निर्माण के लिए एक मेजबान सूचक लेगा, यह कल्पना द्वारा अस्पष्ट है अगर यह पिन की गई स्मृति हो या नहीं हो सकता है। लेकिन आम तौर पर बोलते हुए, इसे इस तरह से बनाई गई पिन की गई स्मृति नहीं बननी चाहिए, क्योंकि होस्ट पॉइंटर ओपनसीएल एपीआई द्वारा आरक्षित नहीं किया गया है और यह स्पष्ट नहीं है कि यह स्मृति में कहां रहता है।


मानचित्र/प्रश्न के बारे में प्रश्न। दोनों ठीक हैं। और वे एक ही प्रदर्शन देंगे।

  • मानचित्र/unmap के लिए:: आप बाद में लेखन/पढ़ने और unmap से पहले मैप करने की आवश्यकता दोनों तकनीकों के बीच अंतर यह है कि है। इस तरह आप डेटा की स्थिरता सुनिश्चित करते हैं। ये एपीआई कॉल हैं, और पूरा करने के साथ-साथ एसिंक्रोनस होने के लिए समय लेते हैं। अच्छी बात यह है कि आपको बफर ऑब्जेक्ट की बजाय किसी अन्य चीज़ को पकड़ने की आवश्यकता नहीं है।
  • के लिए मानचित्र + पढ़ें/लिखें: स्मृति क्षेत्र का निर्माण में आप एक मानचित्र करते हैं और सूचक मूल्य को बचाने के लिए की जरूरत है। फिर, बफर के विनाश पर, आपको पहले unmap करने की जरूरत है और फिर इसे नष्ट कर। आपको buffer+Mapped_Buffer सभी को साथ रखने की आवश्यकता है। अच्छी बात यह है कि अब आप उस मैप किए गए पॉइंटर पर clEnqueueRead/Write कर सकते हैं। एपीआई पिन किए गए डेटा को सुसंगत होने की प्रतीक्षा करेगा और फिर इसे पूरा करने पर विचार करें। इसका उपयोग करना आसान है, क्योंकि यह एक शॉट करने जैसा है + एक शॉट में अनमैप करें।

पढ़ें/लिखें मोड का उपयोग करने के लिए आसान है, दोहराए पढ़ता है, लेकिन जब से तुम एक read only नक्शा नहीं लिख सकते हैं, और न ही एक write only नक्शा नहीं पढ़ा, मैनुअल नक्शा विकल्प के रूप में के रूप में बहुमुखी है विशेष रूप से के लिए। लेकिन सामान्य रूप से उपयोग किए जाने वाले चरों को कभी भी लिखा नहीं जाएगा, और उपाध्यक्ष।


मेरे समझ कि इंटेल सिफारिश, "का प्रयोग करें मानचित्र, नहीं सादे पढ़ें/लिखें" करने के लिए, बल्कि संदर्भित करता है की तुलना में "आप मानचित्र का उपयोग करते हैं, का उपयोग नहीं करते पढ़ें/मैप संकेत से अधिक लिखें" है ।

क्या आपने इंटेल एचडब्ल्यू पर इस एनवीआईडीआईए की सिफारिश की जांच की? मुझे लगता है कि यह काम करना चाहिए, हालांकि मुझे नहीं पता कि वास्तव में ऑपरेशन इष्टतम होगा (जैसा कि एएमडी या एनवीआईडीआईए एचडब्ल्यू में)।

+0

यह वास्तव में अजीब बात है कि आपको मानचित्र/अनमैप के साथ clEnqueueWriteBuffer() का उपयोग करने की आवश्यकता है। चूंकि आप मानचित्र करते हैं, और उसके बाद होस्ट पॉइंटर बदलते हैं, तो आप वास्तव में दोनों CPU और GPU डेटा बदल रहे हैं। जब आप अनैप करते हैं, तो डेटा सीपीयू और जीपीयू पक्ष के बीच सिंक्रनाइज़ किया जाएगा। मैं एमएपी + सीडीटाइन और यूएनएमएपी के बीच एक clEnqueueWriteBuffer करने की आवश्यकता को समझ नहीं पा रहा हूं। बहुत अजीब... –

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