2010-02-07 13 views
6

में प्रत्येक आंतरिक लूप के लिए एक थ्रेड शुरू करना मैं ओपनएमपी के लिए बिल्कुल नया हूं और मैं 2 डी सरणी में प्रत्येक आइटम को संसाधित करने के लिए एक व्यक्तिगत धागा शुरू करने की कोशिश कर रहा हूं।ओपनएमपी

तो अनिवार्य रूप से, इस:

#pragma omp parallel for shared(a,b,c) private(i,j) reduction(+:diff) schedule(dynamic) 
    for (i = 0; i < dimension; i++) { 
     for (int j = 0; j < dimension; j++) { 
      a[i][j] = b[i][j] + c[i][j]; 

यह वास्तव में एक धागा प्रत्येक 2 डी मद के लिए है या नहीं शुरू करता है:

for (i = 0; i < dimension; i++) { 
    for (int j = 0; j < dimension; j++) { 
     a[i][j] = b[i][j] + c[i][j]; 

यह क्या मैं कर रहा हूँ है? मैं इसका परीक्षण कैसे करूं? यदि यह गलत है, तो ऐसा करने का सही तरीका क्या है? धन्यवाद!

नोट: कोड बहुत आसान बना दिया गया है

+0

भाषा का उपयोग कर रहे के साथ टैग कर सकते हैं, हालांकि:

तो मैं कुछ 2 डी ग्रिड बनाने के लिए और (निश्चित 4x4 धागा ग्रिड के लिए उदाहरण) के लिए एक से ग्रिड पर सभी धागे शुरू करने के लिए लगता है आपको मौजूदा टैग में से एक को हटाना होगा। –

+0

अच्छा बिंदु mmyers - संदर्भ के लिए ऐसा लगता है कि वह सी/सी ++ (ओपनएमपी सी/सी ++ और केवल फोर्ट्रान) का उपयोग कर रहा है –

उत्तर

7

केवल बाहरी पाश अपने कोड नमूने में समानांतर है। आप आंतरिक लूप में omp_get_thread_num() प्रिंट करके परीक्षण कर सकते हैं और आप देखेंगे कि, दिए गए i के लिए, थ्रेड नंबर समान है (बेशक, यह परीक्षण निश्चित के बजाए प्रदर्शनकारी है क्योंकि अलग-अलग रन अलग-अलग परिणाम देंगे)। उदाहरण के लिए, के साथ:

#include <stdio.h> 
#include <omp.h> 
#define dimension 4 

int main() { 
    #pragma omp parallel for 
    for (int i = 0; i < dimension; i++) 
     for (int j = 0; j < dimension; j++) 
      printf("i=%d, j=%d, thread = %d\n", i, j, omp_get_thread_num()); 
    } 

मैं:

i=1, j=0, thread = 1 
i=3, j=0, thread = 3 
i=2, j=0, thread = 2 
i=0, j=0, thread = 0 
i=1, j=1, thread = 1 
i=3, j=1, thread = 3 
i=2, j=1, thread = 2 
i=0, j=1, thread = 0 
i=1, j=2, thread = 1 
i=3, j=2, thread = 3 
i=2, j=2, thread = 2 
i=0, j=2, thread = 0 
i=1, j=3, thread = 1 
i=3, j=3, thread = 3 
i=2, j=3, thread = 2 
i=0, j=3, thread = 0 

अपने कोड के बाकी के लिए, आप एक नया सवाल में अधिक जानकारी के डाल करने के लिए चाहते हो सकता है (यह छोटा सा नमूना से बताना मुश्किल है), लेकिन उदाहरण के लिए, आप private(j) नहीं डाल सकते हैं जब j केवल बाद में घोषित किया जाता है। यह उपरोक्त मेरे उदाहरण में स्वचालित रूप से निजी है। मुझे लगता है कि diff एक चर है जिसे हम नमूना में नहीं देख सकते हैं। इसके अलावा, पाश चर i स्वचालित रूप से निजी है (version 2.5 spec से - 3.0 कल्पना में ही)

पाश के लिए लूप निर्माण के लिए के लिए एक के या समानांतर में यात्रा चर कि निर्माण में निजी है ।

संपादित करें: उपर्युक्त सभी कोड आपके द्वारा दिखाए गए कोड के लिए सही है, लेकिन आप निम्न में रुचि रखते हैं। ओपनएमपी संस्करण 3.0 के लिए (उदाहरण के लिए gcc version 4.4 में उपलब्ध है, लेकिन संस्करण 4.3 नहीं) वहां collapse क्लॉज है जहां आप कोड लिख सकते हैं, लेकिन #pragma omp parallel for collapse (2) दोनों लूप के लिए समानांतर करने के लिए (the spec देखें)।

संपादित: ठीक है, मैं जीसीसी 4.5.0 डाउनलोड किया है और इसके बाद के संस्करण कोड भाग गया, लेकिन collapse (2) का उपयोग कर निम्नलिखित उत्पादन प्राप्त करने के लिए, भीतरी पाश अब parallelized दिखा: के लिए

i=0, j=0, thread = 0 
i=0, j=2, thread = 1 
i=1, j=0, thread = 2 
i=2, j=0, thread = 4 
i=0, j=1, thread = 0 
i=1, j=2, thread = 3 
i=3, j=0, thread = 6 
i=2, j=2, thread = 5 
i=3, j=2, thread = 7 
i=0, j=3, thread = 1 
i=1, j=1, thread = 2 
i=2, j=1, thread = 4 
i=1, j=3, thread = 3 
i=3, j=1, thread = 6 
i=2, j=3, thread = 5 
i=3, j=3, thread = 7 

टिप्पणियाँ here (खोज "वर्कअराउंड्स") संस्करण 2.5 में कार्य-आस-पास के लिए भी प्रासंगिक हैं यदि आप दोनों लूप को समानांतर करना चाहते हैं, लेकिन उपरोक्त उद्धृत संस्करण 2.5 spec काफी स्पष्ट है (खंड A.35 में गैर-अनुरूप उदाहरण देखें)।

+0

धन्यवाद, पतन मैं जिस चाल की तलाश में था! – achinda99

0

आप नेस्टेड ओएमपी समांतर फोर्स (omp_set_nested(1) कॉल के बाद) का उपयोग करने का प्रयास कर सकते हैं, लेकिन वे सभी openmp कार्यान्वयन पर समर्थित नहीं हैं।

#pragma omp parallel for 
for(k = 0; k < 16; k++) 
{ 
    int i,j,i_min,j_min,i_max,j_max; 
    i_min=(k/4) * (dimension/4); 
    i_max=(k/4 + 1) * (dimension/4); 
    j_min=(k%4) * (dimension/4); 
    j_max=(k%4 + 1) * (dimension/4); 

    for(i=i_min;i<i_max;i++) 
     for(j=j_min;j<j_max;j++) 
     f(i,j); 

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