मैं ओपनसीएल प्रोग्रामिंग के लिए नया हूँ। मेरे ओपनसीएल अनुप्रयोगों में से एक में, मैं प्रत्येक कर्नेल को लॉन्च करने के बाद clWaitForEvents का उपयोग करता हूं।
मामला एक:
time_start();
cl_event event;
cl_int status = clEnqueueNDRangeKernel(queue, ..., &event);
clWaitForEvents(1, &event);
time_end();
लिया गया समय: 250 एमएस (clWaitForEvents के साथ)
अगर मैं clWaitForEvents () को हटाता हूं, तो मेरा कर्नेल उसी आउटपुट के साथ तेजी से चलता है।
केस 2:
time_start();
cl_event event;
cl_int status = clEnqueueNDRangeKernel(queue, ..., &event);
time_end();
लिया गया समय: 220 एमएस (clWaitForEvents के बिना)
मुझे क्रमिक रूप से 10 अलग-अलग गुठली लॉन्च करनी है। प्रत्येक कर्नेल पिछले कर्नेल के आउटपुट पर निर्भर है। प्रत्येक कर्नेल के बाद clWaitForEvent का उपयोग करने से मेरा निष्पादन समय कुछ 100 एमएस बढ़ जाता है।
अगर मैं clWaitForEvents का उपयोग नहीं करता तो क्या आउटपुट गलत हो सकते हैं? मैं समझना चाहता हूं कि यदि मैं clWaitForEvents या clFinish का उपयोग नहीं करता तो संभवतः क्या गलत हो सकता है।
किसी भी संकेत की सराहना की जाती है।
2 जवाब
उम्मीद है कि थोड़ा कम जटिल उत्तर:
मुझे क्रमिक रूप से 10 अलग-अलग गुठली लॉन्च करनी है। प्रत्येक कर्नेल पिछले कर्नेल के आउटपुट पर निर्भर है।
यदि आप clCreateCommandQueue() कॉल (= सामान्य स्थिति) में CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE प्रॉपर्टी को स्पष्ट रूप से सेट नहीं करते हैं, तो यह एक इन-ऑर्डर कतार होगी। आपको उनमें आदेशों को सिंक्रनाइज़ करने की आवश्यकता नहीं है (वास्तव में आपको ऐसा नहीं करना चाहिए, जैसा कि आप देखते हैं कि यह निष्पादन को काफी धीमा कर सकता है)। दस्तावेज़ देखें:
If the CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE property of a command-queue is not set, the commands enqueued to a command-queue execute in order. For example, if an application calls clEnqueueNDRangeKernel to execute kernel A followed by a clEnqueueNDRangeKernel to execute kernel B, the application can assume that kernel A finishes first and then kernel B is executed. If the memory objects output by kernel A are inputs to kernel B then kernel B will see the correct data in memory objects produced by execution of kernel A.
अगर मैं clWaitForEvents या clFinish का उपयोग नहीं करता तो मैं समझना चाहता हूं कि क्या गलत हो सकता है।
यदि आप एकल इन-ऑर्डर कतार में साधारण चीजें कर रहे हैं, तो आपको clWaitForEvents() की बिल्कुल भी आवश्यकता नहीं है। यह ज्यादातर तब उपयोगी होता है जब आप कई कतारों से कई घटनाओं की प्रतीक्षा करना चाहते हैं, या आप आउट-ऑफ-ऑर्डर कतारों का उपयोग कर रहे हैं, या आप 20 कमांड को एनक्यू करना चाहते हैं, लेकिन चौथे, या कुछ इसी तरह की प्रतीक्षा करें।
एकल इन-ऑर्डर कतार के लिए, clFinish() रिटर्न के बाद सभी कमांड पूरे हो जाएंगे और किसी भी और सभी ईवेंट की स्थिति को पूर्ण या विफल होने के लिए अपडेट किया जाएगा। तो सबसे सरल मामले में आपको घटनाओं से निपटने की ज़रूरत नहीं है, बस आपको जो कुछ भी चाहिए उसे संलग्न करें (हालांकि त्रुटियों के लिए एनक्यू की जांच करें) और clFinish() पर कॉल करें।
ध्यान दें कि यदि आप प्रतीक्षा/फ्लश (WaitForEvents/Finish/a Blocking कमांड) के किसी भी रूप का उपयोग नहीं करते हैं, तो कार्यान्वयन में उतना समय लग सकता है, जितना वह वास्तव में उन कमांड को किसी डिवाइस पर पुश करना चाहता है। IOW आपको चाहिए या तो 1) WaitForEvents का उपयोग करें या समाप्त करें, या 2) अंतिम कमांड के रूप में ब्लॉकिंग कमांड (रीड/राइट/मैप/अनमैप) को एनक्यू करें।
In-order-queue
परोक्ष रूप से प्रत्येक कमांड के पूरा होने की प्रतीक्षा उसी क्रम में करता है जिस क्रम में वे संलग्न हैं लेकिन केवल डिवाइस-साइड पर। इसका मतलब है कि मेजबान को पता नहीं चल सकता कि क्या हुआ।
Out-of-order-queue
कहीं भी किसी भी आदेश आदेश की गारंटी नहीं देता है और इसमें समस्याएं हो सकती हैं।
'वेट-फॉर-इवेंट' एक कमांड की घटना के लिए मेजबान पक्ष की प्रतीक्षा करता है।
'समाप्त' मेजबान पक्ष पर प्रतीक्षा करता है जब तक कि सभी आदेश पूर्ण नहीं हो जाते।
'नॉन ब्लॉकिंग बफर रीड/राइट' होस्ट साइड पर प्रतीक्षा नहीं करता है।
'ब्लॉकिंग बफर रीड/राइट' होस्ट साइड पर प्रतीक्षा करता है लेकिन अन्य कमांड की प्रतीक्षा नहीं करता है।
अनुशंसित समाधान:
- इंटर-कमांड सिंक (अगले कमांड के इनपुट के रूप में कमांड के आउटपुट का उपयोग करने के लिए)
- इन-ऑर्डर-कतार।
- या किसी अन्य को आदेश की घटना पास करना (यदि यह एक आउट-ऑफ-ऑर्डर कतार है)
- इंटर-क्यू (या आउट-ऑफ-ऑर्डर कतार) सिंक (बफर प्रतियों और कर्नेल निष्पादन को ओवरलैप करने के लिए)
- इवेंट को कमांड से दूसरे कमांड में पास करें
- डिवाइस - होस्ट सिंक (रैम में नवीनतम डेटा प्राप्त करने के लिए (या रैम से पहला डेटा प्राप्त करने के लिए) या होस्ट को रोकना)
- बफर कमांड पर ब्लॉक करने का विकल्प सक्षम करें
- या एक क्लफिनिश जोड़ें
- या clWaitForEvent का उपयोग करें
- कमांड पूरा होने पर सूचित रहें (बेंचमार्किंग जैसे कारणों के लिए)
- इवेंट कॉलबैक का उपयोग करें
- या लगातार घटना की स्थिति पूछें(CPU/pci-e उपयोग बढ़ता है)
1 नॉन-ब्लॉकिंग बफर राइट + 1000 x कर्नेल + 1 ब्लॉकिंग बफर को इन-ऑर्डर-क्यू पर पढ़ने से प्रारंभिक डेटा पर 1000 कर्नेल की एक श्रृंखला को सफलतापूर्वक निष्पादित किया जा सकता है और मेजबान पक्ष पर नवीनतम परिणाम प्राप्त कर सकते हैं।
संबंधित सवाल
नए सवाल
opencl
ओपनसीएल (ओपन कम्प्यूटिंग लैंग्वेज) प्रोग्राम लिखने के लिए एक फ्रेमवर्क है जो सीपीयू, जीपीयू और अन्य प्रोसेसर से युक्त विषम प्लेटफार्मों पर निष्पादित होता है।