2010-03-09 15 views
5

के लिए कनवर्ट करने के लिए कैसे करें मैं अपने लूप को STL std :: for_each loop में कनवर्ट करना चाहता हूं।लूप से STL for_each कथन

bool CMyclass::SomeMember() 
{ 
    int ii; 
     for(int i=0;i<iR20;i++) 
      { 
       ii=indexR[i]; 
       ishell=static_cast<int>(R[ii]/xStep); 
       theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]); 
       al2[ishell] += massp*cos(fm*theta); 
      } 
} 

असल में मैं जी से समानांतर एसटीएल उपयोग करने के लिए योजना बना रहा था ++ 4,4

g++ -D_GLIBCXX_PARALLEL -fopenmp 

जो करता है, तो कोड मानक एसटीएल पुस्तकालय में लिखा है बदलाव के बिना समानांतर में कोड चलाने की अनुमति दे सकता है।

+1

क्यों नहीं पहले '#pragma omp समानांतर' के लिए पहले? – stephan

+1

+1 स्टीफन, हालांकि tje 'al2 [ishell]' ** + = ** को कमी खंड या परमाणु बाधा की आवश्यकता है। यह सुनिश्चित नहीं है कि यह एसटीएल समानांतर में कैसे अनुवाद करेगा। – peterchen

+0

हां समाधानों में से एक "#pragma omp समानांतर" होगा लेकिन हमेशा प्रत्येक के लिए साझा और निजी चर पर विचार करने की आवश्यकता होगी। जो हमेशा त्रुटियों के स्रोतों में से एक है। – Arman

उत्तर

5

आपको लूप बॉडी को एक अलग समारोह या मज़ेदार में अलग करने की आवश्यकता है; मैंने माना है कि सभी अविकसित चर सदस्य चर हैं।

void CMyclass::LoopFunc(int ii) { 
    ishell=static_cast<int>(R[ii]/xStep); 
    theta=atan2(data->pPOS[ii*3+1], 
    data->pPOS[ii*3]); 
    al2[ishell] += massp*cos(fm*theta); 
} 

bool CMyclass::SomeMember() { 
    std::for_each(&indexR[0],&indexR[iR20],std::tr1::bind(&CMyclass::LoopFunc,std::tr1::ref(*this)); 
} 
+0

अच्छा !! यह अवधारणा सबसे अच्छी है। धन्यवाद! – Arman

+1

क्या यह समाधान थ्रेड सुरक्षित है? मैं नहीं मानूंगा। यदि समानांतर 'for_each' लूप को विभिन्न धागे में विभाजित करता है, तो वे सभी किसी भी प्रकार की सुरक्षा के बिना समान सदस्य विशेषताओं तक पहुंच पाएंगे। –

+0

उसे थ्रेड सुरक्षा के बारे में सावधान रहने की आवश्यकता होगी - उसका मूल कोड स्पष्ट नहीं करता था कि कौन से चर स्थानीय थे और जो सदस्य चर थे। इंडेक्स I और इंडेक्स i + 1 को अलग-अलग धागे में लिखना इंक की सरणी के लिए सुरक्षित होना चाहिए? –

0

आपको लूप बॉडी को फ़ंक्शन या फ़ंक्शन में कनवर्ट करने की आवश्यकता होगी। वहां बहुत सारे अव्यवस्थित चर हैं, इसलिए मैं लूप बॉडी को अलग करने के तरीके को आसानी से नहीं बता सकता। यहां एक स्टैब है:

class DoStuff 
{ 
    int* R; 
    int xStep; 
    Data* data; 
    double massp; 
    double fm; 
    double* al2; 
public: 
    DoStuff(int* R_, int xStep_, Data* data_, double massp_, double fm_, double* al2_) : 
    R(R_), xStep(xStep_), data(data_), massp(massp_), fm(fm_), al2(al2_) {} 

    void operator()(int ii) 
    { 
    int ishell = static_cast<int>(R[ii]/xStep); 
    double theta = atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]); 
    al2[ishell] += massp*cos(fm*theta); 
    } 
}; 

for_each(indexR, indexR+iR20, DoStuff(R, xStep, data, massp, fm, al2)); 
+0

आरंभिक सूची का उपयोग करते समय , आपको तर्कों का नाम बदलने की आवश्यकता नहीं है। अर्थात। 'आर (आर)' आदि ठीक काम करेगा। –

+0

हां, मुझे इसके बारे में पता है। –

1
class F { 
    public: 
    void operator()(int ii) { 
       ishell=static_cast<int>(R[ii]/xStep); 
       theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]); 
       al2[ishell] += massp*cos(fm*theta); 
    } 
    F(int[] r): //and other parameters should also be passed into the constructor 
     r_(r) {} 
    void: 
    int[] r_; // refers to R[ii] array 
    // and other parameters should also be stored 
}; 

F f(R); // pass other parameters too 
for_each(&indexR[0], &indexR[iR20], f); 

हालांकि यह एक अच्छा विचार यह "स्वचालित बनता है" का उपयोग करने के बाद से आप मन में प्रत्येक समानांतर गणना की grainsize रखने की जरूरत नहीं हो सकता है - मुझे यकीन है कि कितनी अच्छी तरह संकलक लेता है नहीं कर रहा हूँ खाते में अनाज का आकार।

+0

यह अच्छा लग रहा है, लेकिन कल्पना करें कि मेरे पास कुछ मेम्बर() फ़ंक्शन में कई लूप हैं और हमें प्रत्येक लूप के लिए क्लास जैसे क्लास को परिभाषित करने की आवश्यकता है। – Arman

+0

हां। यह कार्यात्मक प्रोग्रामिंग का सी ++ तरीका है। यदि आप ऐसा करने वाले हैं, तो आप इंटेल टीबीबी का भी उपयोग कर सकते हैं और समांतरता के लिए समानांतर_for का उपयोग कर सकते हैं (टीबीबी जिस तरह से मैं पसंद करता हूं)। –

+0

हां टीबीबी अच्छी तरह डिज़ाइन किया गया है, लेकिन मैं एक शोधकर्ता हूं, मैं जीपीएल सॉफ्टवेयर पसंद करता हूं। – Arman

1

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

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