2013-11-21 5 views
6

के साथ अनुक्रमिक लूप में समांतर लूप को कैसे घोंसला करना है मैं वर्तमान में ओपनएमपी के साथ मैट्रिक्स गणना पर काम कर रहा हूं। मेरे कोड में मेरे पास कई लूप हैं, और इसके बजाय प्रत्येक लूप #pragma omp के लिए समानांतर कॉल करने के लिए [...] (जो सभी धागे बनाते हैं और उन्हें ठीक से नष्ट कर देते हैं) मैं शुरुआत में उन सभी को बनाना चाहता हूं, और ओवरहेड से बचने के लिए कार्यक्रम के अंत में उन्हें हटा दें। मैं चाहता हूँ की तरह कुछ:ओपनएमपी

#pragma omp parallel 
{ 
    #pragma omp for[...] 
    for(...) 

    #pragma omp for[...] 
    for(...) 
} 

समस्या यह है कि मैं कुछ भागों है उन केवल एक धागा द्वारा निष्पादित किया जाना है, लेकिन एक पाश, जिसमें में लूप उन समानांतर में निष्पादित रहना होगा ... यह यह कैसा दिखाई देता है:

//have to be execute by only one thread 
int a=0,b=0,c=0; 
for(a ; a<5 ; a++) 
{ 

    //some stuff 

    //loops which have to be parallelize 
    #pragma omp parallel for private(b,c) schedule(static) collapse(2) 
    for (b=0 ; b<8 ; b++); 
     for(c=0 ; c<10 ; c++) 
     { 
      //some other stuff 
     } 

    //end of the parallel zone 
    //stuff to be execute by only one thread 

} 

(पाश सीमाओं मेरी उदाहरण में काफी छोटे हैं मेरे कार्यक्रम में पुनरावृत्तियों की संख्या 20.000 जब तक चला जाता है कर सकते हैं ...।) मेरा पहला विचार में से एक इस तरह कुछ करने के लिए था :

//have to be execute by only one thread 
#pragma omp parallel //creating all the threads at the beginning 
{ 
    #pragma omp master //or single 
    {   
     int a=0,b=0,c=0; 
     for(a ; a<5 ; a++) 
     { 

      //some stuff 

      //loops which have to be parallelize 
      #pragma omp for private(b,c) schedule(static) collapse(2) 
      for (b=0 ; b<8 ; b++); 
       for(c=0 ; c<10 ; c++) 
       { 
        //some other stuff 
       } 

      //end of the parallel zone 
      //stuff to be execute by only one thread 

     } 
    } 
} //deleting all the threads 

यह संकलित नहीं करता है, मुझे यह त्रुटि जीसीसी से मिलती है: "कार्य-साझाकरण क्षेत्र को कार्य-साझाकरण, महत्वपूर्ण, आदेशित, मास्टर या स्पष्ट कार्य क्षेत्र के अंदर घनिष्ठ रूप से घोंसला नहीं किया जा सकता है"।

मुझे पता है कि यह निश्चित रूप से "गलत" घोंसले से आता है, लेकिन मुझे समझ में नहीं आता कि यह क्यों काम नहीं करता है। क्या मुझे समांतर क्षेत्र से पहले बाधा जोड़ने की ज़रूरत है? मैं थोड़ा हारा हूं और यह नहीं जानता कि इसे कैसे हल किया जाए।

आपकी मदद के लिए अग्रिम धन्यवाद। चीयर्स।

उत्तर

3

आपके अंतिम कोड रूपरेखा में आप एक समानांतर क्षेत्र घोषित करते हैं, इसके अंदर एक मास्टर निर्देश का उपयोग यह सुनिश्चित करने के लिए करता है कि केवल मास्टर थ्रेड ब्लॉक को निष्पादित करता है, और मास्टर ब्लॉक के अंदर सभी थ्रेडों में लूप को समानांतर करने का प्रयास करता है। आप यह जानने का दावा करते हैं कि संकलक त्रुटियां गलत घोंसले से उत्पन्न होती हैं लेकिन आश्चर्य है कि यह क्यों काम नहीं करता है।

यह काम नहीं करता है क्योंकि कोड के एक क्षेत्र के भीतर कई धागे में काम वितरित करना जो केवल एक धागा निष्पादित करेगा, कोई समझ नहीं आता है।

आपका पहला छद्म कोड बेहतर है, लेकिन आप शायद यह इस तरह का विस्तार करना चाहते:

#pragma omp parallel 
{ 
    #pragma omp for[...] 
    for(...) 

    #pragma omp single 
    { ... } 

    #pragma omp for[...] 
    for(...) 
} 

single निर्देश सुनिश्चित करता है कि कोड के ब्लॉक यह encloses केवल एक धागा द्वारा निष्पादित किया जाता है। master निर्देश single के विपरीत बाहर निकलने पर बाधा का भी अर्थ है; आप इस व्यवहार को nowait खंड के साथ बदल सकते हैं।

+0

आपके उत्तर के लिए धन्यवाद। मैं समानांतर के लिए एक आसान संरचना के लिए अपने कोड को पुन: व्यवस्थित करने का प्रयास करूंगा। – user3014051

3

अधिकांश ओपनएमपी रनटाइम "सभी धागे बनाते हैं और उन्हें ठीक बाद में नष्ट नहीं करते हैं"। धागे पहले ओपनएमपी अनुभाग की शुरुआत में बनाए जाते हैं और प्रोग्राम समाप्त होने पर नष्ट हो जाता है (कम से कम इंटेल के ओपनएमपी कार्यान्वयन यह कैसे करता है)। कई छोटे लोगों के बजाय एक बड़े समांतर क्षेत्र का उपयोग करने से कोई प्रदर्शन लाभ नहीं है।

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

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