2010-09-23 25 views
19

क्या ओपनएमपी एक चर के अनुपात में कमी का समर्थन करता है जो एक सरणी का प्रतिनिधित्व करता है?क्या ओपनएम के साथ सरणी में कमी करना संभव है?

यह निम्नलिखित की तरह कुछ काम करेगा ...

float* a = (float*) calloc(4*sizeof(float)); 
omp_set_num_threads(13); 
#pragma omp parallel reduction(+:a) 
for(i=0;i<4;i++){ 
    a[i] += 1; // Thread-local copy of a incremented by something interesting 
} 
// a now contains [13 13 13 13] 

आदर्श रूप में, वहाँ के लिए एक omp समानांतर के लिए कुछ इसी तरह होगा, और यह समझ बनाने के लिए के लिए आप धागे का एक बड़ा पर्याप्त संख्या है, संचय बाइनरी पेड़ के माध्यम से होगा।

+7

केवल फोर्टन – Anycorn

+1

में हो सकता है कि आप थोड़ा और समझा सकें कि आप वास्तव में क्या करना चाहते हैं। सीरियल कोड प्रदान करने में मदद मिल सकती है। – FFox

+0

थोड़ा और अधिक खोदना, ऐसा लगता है कि "केवल फोर्ट्रान में" जवाब है।मैंने लूप के बाहर स्थानीय प्रतियों की एक बड़ी श्रृंखला को आवंटित कर दिया, जिससे धागे लूप के भीतर अपनी प्रतियों में जमा हो जाते हैं, फिर लूप के बाद एक वैश्विक सरणी में जमा हो जाते हैं, फिर भी समानांतर क्षेत्र के अंदर, महत्वपूर्ण अनुभाग। –

उत्तर

3

केवल ओपनएमपी 3.0 में फोरट्रान में, और शायद कुछ निश्चित कंपाइलरों के साथ। अब

http://wikis.sun.com/display/openmp/Fortran+Allocatable+Arrays

+3

का उपयोग करना चाहते हैं, यह अब ओपनएमपी 4.5 के बाद से संभव है; नीचे चेन जियांग का जवाब देखें। असल में, आपको _array section_ निर्दिष्ट करना होगा (ओपनएमपी 4.5 spec के खंड 2.4, पृष्ठ 44 देखें।)। आपका #pragma विनिर्देश इस तरह दिखेगा: '#pragma omp समानांतर कमी (+: a [: 4])' हालांकि इसके साथ सावधान रहें, आपको यह समझना होगा कि प्रत्येक थ्रेड अपना स्वयं का संस्करण आवंटित करेगा सरणी अनुभाग; यदि आप इसे कई धागे के साथ बड़े सरणी पर करते हैं, तो आप अपनी मेमोरी को विस्फोट करने की आवश्यकता बना सकते हैं। –

1

ओपनएमपी सरणी या संरचना प्रकार चर पर कटौती नहीं कर सकता (restrictions देखें)।

आप private और shared क्लॉज पर भी पढ़ना चाहेंगे। private एक चर को प्रत्येक थ्रेड के लिए निजी घोषित करता है, जहां shared सभी धागे के बीच एक चर को साझा करने की घोषणा करता है। मुझे ओपनएमपी और एरे के संबंध में इस question का उत्तर भी बहुत उपयोगी पाया गया।

2

नवीनतम OpenMP 4.5 कल्पना C/C++ सरणियों की कमी का समर्थन करता है है:

पर पिछले उदाहरण (उदाहरण 3) देखें। http://openmp.org/wp/2015/11/openmp-45-specs-released/

और नवीनतम जीसीसी 6.1 भी इस सुविधा का समर्थन किया है। http://openmp.org/wp/2016/05/gcc-61-released-supports-openmp-45/

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

3

सी और सी ++ के लिए ओपनएमपी 4.5 के साथ अब्रे कमी अब संभव है। यहाँ एक उदाहरण है:

#include <iostream> 

int main() 
{ 

    int myArray[6] = {}; 

    #pragma omp parallel for reduction(+:myArray[:6]) 
    for (int i=0; i<50; ++i) 
    { 
    double a = 2.0; // Or something non-trivial justifying the parallelism... 
    for (int n = 0; n<6; ++n) 
    { 
     myArray[n] += a; 
    } 
    } 
    // Print the array elements to see them summed 
    for (int n = 0; n<6; ++n) 
    { 
    std::cout << myArray[n] << " " << std::endl; 
    } 
} 

आउटपुट:

100 
100 
100 
100 
100 
100 

मैं जीसीसी 6.2 के साथ इस संकलित। आप देख सकते हैं जो आम संकलक संस्करणों यहाँ OpenMP 4.5 सुविधाओं का समर्थन: है कि ऊपर टिप्पणियों से http://www.openmp.org/resources/openmp-compilers/

नोट जबकि इस सुविधाजनक वाक्य रचना है, यह प्रत्येक थ्रेड के लिए प्रत्येक सरणी खंड की प्रतियां बनाने से ओवरहेड्स का एक बहुत आह्वान कर सकते हैं।

0

ओपनएमपी ओपनएमपी 4.5 और जीसीसी 6.3 (और संभवतः निचला) के रूप में इस ऑपरेशन को निष्पादित कर सकता है। एक उदाहरण कार्यक्रम इस प्रकार है:

#include <vector> 
#include <iostream> 

int main(){ 
    std::vector<int> vec; 

    #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) 

    #pragma omp parallel for default(none) schedule(static) reduction(merge: vec) 
    for(int i=0;i<100;i++) 
    vec.push_back(i); 

    for(const auto x: vec) 
    std::cout<<x<<"\n"; 

    return 0; 
} 

ध्यान दें कि omp_out और omp_in विशेष चर रहे हैं और कि declare reduction के प्रकार वेक्टर आप पर कम करने के लिए योजना बना रहे हैं मेल खाना चाहिए।

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